下面的代码应该输出弦
LANG=C ;
echo 'aString12 theString34 otherString56' | \
sed "s;aString12 \(theString34\) anotherString56;$(printf '%s' "\1" | sed 's;[0-9]\{2\}$;;');"
...但它输出字符串34。这34应该被消除| sed 的;[0-9]{2}$;;');但事实并非如此。
我需要通过$(printf '%s' "\1" | sed 's;[0-9]\{2\}$;;')
仅更改该部分来解决此问题,并且不应通过用变量替换该部分代码来解决此问题。
提前致谢。
答案1
sed
您的问题是,即使在命令启动之前,也会执行嵌入式命令替换。当 shell 找出要调用的参数时,它会被执行sed
。
sed
您可以隔离需要使用的字符串部分,然后使用第二个替换命令对其进行修改,而不是尝试从内部调用外部实用程序:
echo 'aString12 theString34 otherString56' |
sed -e 's/aString12 \(theString34\) otherString56/\1/' \
-e 's/[0-9]\{2\}$//'
这会用第一个表达式中捕获的部分替换整行,然后将第二个替换应用于缓冲区中剩余的内容。
要仅在第一个替换执行某些操作时应用第二个替换,您可以首先尝试匹配表达式,如果不匹配则分支到脚本末尾(使用!b
)。如果它做过匹配,您应用两个替换:
echo 'aString12 theString34 otherString56' |
sed -e '/aString12 \(theString34\) otherString56/!b' \
-e 's//\1/' \
-e 's/[0-9]\{2\}$//'
第一个替换 ( s//\1/
) 中的空正则表达式将重用最近匹配的模式,即前一个表达式中的模式。