【问题标题】:Append new line after match in multiple files with sed使用 sed 在多个文件中匹配后追加新行
【发布时间】:2026-02-17 11:50:01
【问题描述】:

我正在写一个脚本

脚本的一个目标是在多个.yml 文件中递归地在匹配后附加一个新的代码行,并带有foo

# Append new line after match in multiple files with sed
## sed -i -se "s/\foo/bar/g" *.yml
grep -rl foo * .| xargs sed -i -e "s/\foo/a bar/g" *.yml

预计在每次与 foo 匹配后,因为 /abar 将被添加到所有 @987654324 的新行中@ 文件。

我得到 意外 Sed 输出: sed: can't read *.yml: No such file or directory

详情:

  1. 操作系统:Debian GNU/Linux 10
  2. sed --version: sed (GNU sed) 4.7

【问题讨论】:

  • 你为什么要使用xargs,还要给sed一个文件名参数?

标签: bash sed


【解决方案1】:

您使用xargs 提供文件名参数。您也不应该使用 *.yml 作为参数。 shell 会将其扩展为当前目录中的.yml 文件,如果没有,则会出现错误。

如果您希望 grep -r 仅检查 .yml 文件,请使用 --include 选项。

grep -rl --include='*.yml' foo . | xargs sed -i -e "s/foo/a bar/g"

请注意,s 命令不用于在一行之后追加新行。它用于在同一行内进行替换。 s/foo/ a bar/g 将所有的foo 替换为a bar。如果你想追加,去掉s 命令。此外,您不要将/g 放在a 命令的末尾。

grep -rl --include='*.yml' foo . | xargs sed -i -e "/foo/a bar"

How to insert text after a certain string in a file?

【讨论】:

  • 嗨,现在测试它输出:sed: -e expression #1, char 45: Invalid back reference
  • 这毫无意义。表达式中只有大约 12 个字符,而不是 45 个。
  • 您没有使用a 命令在一行之后追加。你有s/foo/a bar/,这意味着将foo替换为a bar
  • 这可能是因为你在开头有多余的s,所以命令没有被正确理解。
  • 最后不需要/g,这是替换命令的一部分,而不是附加命令。