如何用 sed 仅替换第一次出现的内容?

如何用 sed 仅替换第一次出现的内容?

原始文件

claudio
antonio
claudio
michele

我只想将第一次出现的“claudio”更改为“claudia”,以便得到以下结果:

claudia
antonio
claudio
michele

我已经尝试过以下方法:

sed -e '1,/claudio/s/claudio/claudia/' nomi

上面的命令执行全局替换(它替换所有出现的“claudio”)。为什么?

答案1

如果您使用的是 GNU sed,请尝试:

sed -e '0,/claudio/ s/claudio/claudia/' nomi

sed不会开始检查结束范围的正则表达式,直到开始该范围的线。

man sed(POSIX 联机帮助页,重点是我的):

具有两个地址的编辑命令应从与第一个地址匹配的第一个模式空间中选择包含范围下一个模式空间与第二个相匹配。

但该0地址不是标准的,这是sed任何其他实现都不支持的 GNU 扩展sed

使用awk

工作范围awk更符合您的预期:

$ awk 'NR==1,/claudio/{sub(/claudio/, "claudia")} 1' nomi
claudia
antonio
claudio
michele

解释:

  • NR==1,/claudio/

    这是一个从第 1 行开始到第一次出现 结束的范围claudio

  • sub(/claudio/, "claudia")

    当我们在范围内时,将执行此替代命令。

  • 1

    这是 awk 的打印行的神秘简写。

答案2

新版本的 GNUsed支持该-z选项。

通常,sed 通过读取字符串直到行尾字符(换行符或回车符)来读取行。
GNU 版本的 sed 在 4.2.2 版本中添加了一个功能来使用“NULL”字符代替。如果您有使用 NULL 作为记录分隔符的文件,这会很有用。某些 GNU 实用程序可以生成使用 NULL 而不是新行的输出,例如“find . -print0”或“grep -lZ”。

sed当您想要在不同的线路上工作时,可以使用此选项。

echo 'claudio
antonio
claudio
michele' | sed -z 's/claudio/claudia/'

回报

claudia
antonio
claudio
michele

答案3

总结

GNU 语法:

sed '/claudio/{s//claudia/;:p;n;bp}' file

或者甚至(仅使用一次要替换的单词:

sed '/\(claudi\)o/{s//\1a/;:p;n;bp}' file

或者,用 POSIX 语法:

sed -e '/claudio/{s//claudia/;:p' -e 'n;bp' -e '}' file

适用于任何 sed、进程仅有的查找第一个claudio, 所需的行数尽可能多,即使claudio位于第一行,并且由于仅使用一个正则表达式字符串而更短。

细节

仅更改一条线你需要选择只有一行。

使用1,/claudio/(来自您的问题)选择:

  • 从第一行开始(无条件)
  • 下一个包含字符串 的行claudio
$ cat file
claudio 1
antonio 2
claudio 3
michele 4

$ sed -n '1,/claudio/{p}' file
claudio 1
antonio 2
claudio 3

选择任何包含 的行claudio,使用:

$ sed -n `/claudio/{p}` file
claudio 1
claudio 3

并且仅选择第一的 claudio在文件中,使用:

sed -n '/claudio/{p;q}' file
claudio 1

然后,您只能在该行上进行替换:

sed '/claudio/{s/claudio/claudia/;q}' file
claudia 1

这只会改变第一的行中出现正则表达式匹配,即使可能有多个第一的与正则表达式匹配的行。

当然,/claudio/正则表达式可以简化为:

$ sed '/claudio/{s//claudia/;q}' file
claudia 1

然后,唯一缺少的是打印所有其他未修改的行:

sed '/claudio/{s//claudia/;:p;n;bp}' file

答案4

您可以使用awk标志来了解替换是否已经完成。如果没有,请继续:

$ awk '!f && /claudio/ {$0="claudia"; f=1}1' file
claudia
antonio
claudio
michele

相关内容