sed 使用模式替换字符串内的子字符串

sed 使用模式替换字符串内的子字符串

我正在尝试替换模式的一部分,例如,如果我有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,在echoing之前需要一个分号 ( )。

     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

相关内容