sed 匹配美元和单引号字符

sed match dollar and single quote characters

我的文件中有以下字符串:

"sequence A$_{0}$B$_{}$C$_{'0}$"

我想将出现在 $_{ 之后的任何单引号移到它之前,即

"sequence A$_{0}$B$_{}$C'$_{0}$"

这是我的 sed 命令(使用 # 作为分隔符),仅用于引号部分:

$ echo "$_{'0}$" | sed "s#$_{'#'$_{#g"
'$_{0}$

所以这行得通。但是我的文本包含不应匹配的字符串,例如

$ echo "$_{0}$" | sed "s#$_{'#'$_{#g"
/home/ppatest/texlive/2010/texmf{0}$`  

我知道 $_ 给出了上一个命令的最后一个参数。我检查了:

$ echo $_
/home/ppatest/texlive/2010/texmf

但我不明白为什么 $_{' 匹配 "$_{0}$"

此外,我发现为了防止 Unix shell 将美元符号解释为 shell 变量,脚本应该放在单引号中。但我不能这样做,因为我也在匹配单引号。

您当前的方法在 sed 中使用双引号来处理单引号。但是,如您所见,这会产生 $ 的扩展,因此您最终可能会遇到更广泛的问题。

我建议使用带单引号的 sed 表达式。要匹配和替换单引号,您需要关闭前导 ',将 ' 括在 " 中,然后再次打开表达式:

$ echo "he'llo" | sed 's#'"'"'#X#'
heXllo

你的情况:

sed 's#$_{'"'"'#'"'"'$_{#g' file

这样,您可以继续使用单引号并防止 $ 的扩展。

测试

$ cat a
hello $_{'0}$ bye
$_{'0}$
yeah
$ sed 's#$_{'"'"'#'"'"'$_{#g' a
hello '$_{0}$ bye
'$_{0}$
yeah
echo "$_{'0}$" | sed "s#\($_{\)'#'#g"
  • 使用双引号时转义 $
  • 尽可能使用群组避免混淆$
  • 当单引号是模式的一部分时使用双引号