我正在尝试替换模式的一部分,例如,如果我有col(3,B,14)
,在应用sed
命令后,我想获得col(3,B,t14)
将字符添加t
到模式中的第三个参数。
我正在尝试:
s="col(3,B,14)"
echo $s | sed 's/col([0-9],[A-Z],[0-9])/col([0-9],[A-Z],t[0-9])/g'
但是,它返回的是原始字符串。如果您能提供一些建议,我将不胜感激。谢谢。
答案1
你似乎对工作原理有点困惑sed
,所以我会一步一步讲解。我的“答案”是这样的:
s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1t/g'
解释
这里有几个问题。
;
首先,在定义变量之后s
,在echo
ing之前需要一个分号 ( )。s="col(3,B,14)"; echo $s
接下来,
sed
通过 进行代换s/pattern/replacement/
,其中pattern
是正则表达式,但其中replacement
不是。也就是说,[0-9]
在中输入类似的东西replacement
不会代表任何数字,而是代表五个字符:[
,,,,和。0
-
9
]
此外,
/g
末尾的用于对模式的每个匹配项继续在字符串上应用替换,因此如果您有如下一行:echo hello world | sed 's/o/z/g'
那么输出将是:
hellz wzrld
然而:
echo hello world | sed 's/o/z/'
将会得到:
hellz world
现在让我们移除你的替换者:
s="col(3,B,14)"; echo $s | sed 's/col([0-9],[A-Z],[0-9])/replacement/g'
将注意力转向您使用的正则表达式模式,它表示“匹配类似 的字符串
col(<single digit>,<uppercase letter>,<single digit>)
”。请注意,最后[0-9]
一部分不会匹配14
,因为14
是两位数,因此您的模式将匹配col(3,B,1)
,但不会匹配col(3,B,14)
。要匹配一个或多个数字,您可以使用[0-9][0-9]*
。要按需要进行替换,最好的方法是使用捕获组。捕获组“记住”匹配的一部分以供以后使用。将要记住的模式部分放在
\(
和周围,以便以后引用它:\)
\1
s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1replacement/g'
这将匹配
col(<single digit>,<uppercase letter>,
,因此直到您想要添加 的位置t
。所有这些匹配的内容都将放回到替换 (\1
) 中,后跟您添加的任何文本(在本例中,我们添加文字“replacement”)。输入中未匹配的任何剩余文本将不受影响。以上将输出:col(3,B,replacement14)
因此如果我们现在在
replacement
字符串中放入一个“t”:s="col(3,B,14)"; echo $s | sed 's/\(col([0-9],[A-Z],\)/\1t/g'
我们得到:
col(3,B,t14)
如果你想学得好sed
,我可以推荐一个非常好的教程:https://www.grymoire.com/Unix/Sed.html