命令行:在 grep 匹配的所有文件名中搜索和替换

新手上路,请多包涵

我正在尝试在 grep 匹配的所有文件中搜索和替换字符串:

grep -n 'foo' * 会给我以下形式的输出:

 [filename]:[line number]:[text]

对于 grep 返回的每个文件,我想通过将 foo 替换为 bar 来修改文件。

原文由 Michael Kristofik 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

您的意思是在所有与 grep 匹配的文件中搜索并替换字符串?

 perl -p -i -e 's/oldstring/newstring/g' `grep -ril searchpattern *`

编辑

因为这似乎是一个相当受欢迎的问题,所以我想更新一下。

现在我主要使用 ack-grep 因为它更人性化。所以上面的命令是:

 perl -p -i -e 's/old/new/g' `ack -l searchpattern`

要处理文件名中的空格,您可以运行:

 ack --print0 -l searchpattern | xargs -0 perl -p -i -e 's/old/new/g'

您可以使用 ack-grep 做更多事情。假设您只想将搜索限制为 HTML 文件:

 ack --print0 --html -l searchpattern | xargs -0 perl -p -i -e 's/old/new/g'

如果空白不是问题,它甚至更短:

 perl -p -i -e 's/old/new/g' `ack -l --html searchpattern`
perl -p -i -e 's/old/new/g' `ack -f --html` # will match all html files

原文由 armandino 发布,翻译遵循 CC BY-SA 3.0 许可协议

根据您提供的示例,这似乎是您想要的:

 sed -i 's/foo/bar/g' *

它不是递归的(它不会下降到子目录中)。对于在整个树中替换选定文件的一个很好的解决方案,我会使用 find:

 find . -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;

*.html 是文件必须匹配的表达式, .bak 之后的 -i 复制原始文件,扩展名为 .bak(可以是您喜欢的任何扩展名)和 g 在 sed 表达式的末尾告诉 sed 替换一行上的多个副本(而不仅仅是第一个)。要查找的 -print 可以方便地显示正在匹配的文件。所有这些都取决于您系统上这些工具的确切版本。

原文由 MattJ 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题