如何仅在第一次出现的匹配行上进行替换?

How can I make a substitution on the line of first occurrence of a match only?

我有一个看起来像这样的文件

000099990000 Carlos C
000099990000 Ana B
000099990000 Ana A Test
000099990000 Ana B
000099990000 Carlos C

我只想找到第一次出现的Ana B,然后将匹配行的9999部分替换为1111

我是运行下面一行:

sed -i '0,/Ana B/ s/9999/1111/' file.txt

但我得到以下结果:

000011110000 Carlos C
000011110000 Ana B
000099990000 Ana A Test
000099990000 Ana B
000099990000 Carlos C

所以 sed 正在替换所有行,直到第一次出现 Ana B。我的命令有什么问题?

$ sed '0,/Ana B/ { //s/9999/1111/ }' ip.txt
000099990000 Carlos C
000011110000 Ana B
000099990000 Ana A Test
000099990000 Ana B
000099990000 Carlos C
  • { //s/9999/1111/ }这里的{}允许分组命令只在满足0,/Ana B/条件时执行
  • // 将重用上次使用的正则表达式,与使用 /Ana B/ 相同 - 这将确保仅包含 Ana B 的行被更改


你也可以在这里使用awk

$ awk '/Ana B/ && !c++{sub(/9999/, "1111")} 1' ip.txt
000099990000 Carlos C
000011110000 Ana B
000099990000 Ana A Test
000099990000 Ana B
000099990000 Carlos C
  • /Ana B/ && !c++ 如果行包含 Ana B 并且如果 c 为零(未初始化变量的默认值)
    • 因为 ++ 下一次 c 将是 1 并且条件将失败(请注意 Ana B 的非常大的匹配可能导致溢出并且 c 再次成为 0)
  • sub(/9999/, "1111")9999 更改为 1111
  • 1 打印 [=32=] 内容的惯用方式(输入记录)