如何仅在首次匹配的行上进行替换?

时间:2019-04-03 03:17:55

标签: awk sed text-processing

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

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。我的命令出了什么问题?

1 个答案:

答案 0 :(得分:2)

$ 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
  • 0sub(/9999/, "1111")更改为9999
  • 1111的惯用方式来打印1(输入记录)的内容