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