从以下 sed 命令获取错误:
echo 20130521_OnePKI_p107336_APP.pfx | sed -e 's/_\([pP][0-9]+\)_/\1/'
它不是返回p107336
,而是返回完整的文件名20130521_OnePKI_p107336_APP.pfx
。
任何想法为什么会发生这种情况,以及如何将输出限制为我想要的模式?
捕获应该用括号转义,您可以使用不区分大小写的 match i
,此外,您正在用捕获的部分替换捕获部分,因此不会进行任何更改。这个匹配整行并将其替换为捕获的模式:
sed -e 's/.*_\([pP][0-9][0-9]*\)_.*/\1/'
更简单的方法可能是使用 grep:
echo 20130521_OnePKI_p107336_APP.pfx | egrep -o "[pP][0-9]+"
“-o”告诉 grep 只打印输入的匹配部分。
正则表达式[pP][0-9]+
原则上匹配任何以一个或多个数字开头p
或P
后跟一个或多个数字的子字符串。该字符串"20130521_OnePKI_p107336_APP.pfx"
具有与该模式匹配的子字符串,因此整个字符串与正则表达式匹配。
当在左侧的整个正则表达式周围用括号分组并在右侧引用它时,就像你在你所做的那样,'s/([pP][0-9]+)/\1/'
你基本上是在说“用自己替换匹配”,这自然会产生与第一个相同的字符串地方。
您需要从头开始匹配整个字符串,然后将该字符串的一部分分组,如前所述。然后您可以参考右侧的该部分以从较大的字符串中提取它。
在 shell 中工作时,您需要适当地转义表达式。
您必须转义括号和+
. 还要匹配所有字符串并仅用您希望的部分替换所有字符串(.*
字符串之前和结尾):
... | sed -e 's/^.*\([pP][0-9]\+\).*$/\1/'