命令行:在 grep 匹配的所有文件名中搜索并替换
我正在尝试搜索并替换 grep 匹配的所有文件中的字符串:
grep -n 'foo' *
将以以下形式提供输出:
[filename]:[line number]:[text]
对于 grep 返回的每个文件,我想通过将 foo
替换为 bar
来修改文件。
I'm trying to search and replace a string in all files matched by grep:
grep -n 'foo' *
will give me output in the form:
[filename]:[line number]:[text]
For each file returned by grep, I'd like to modify the file by replacing foo
with bar
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
根据您给出的示例,这似乎是您想要的:
它不是递归的(它不会下降到子目录中)。 对于在整个树中替换选定文件的良好解决方案,我将使用 find:
*.html
是文件必须匹配的表达式,之后的
制作原始文件的副本,带有 .bak 扩展名(可以是您喜欢的任何扩展名),sed 表达式末尾的.bak
-ig
告诉 sed 替换多个复制一行(而不是仅复制第一行)。-print
to find 可以方便地显示哪些文件正在匹配。 所有这些都取决于您系统上这些工具的确切版本。This appears to be what you want, based on the example you gave:
It is not recursive (it will not descend into subdirectories). For a nice solution replacing in selected files throughout a tree I would use find:
The
*.html
is the expression that files must match, the.bak
after the-i
makes a copy of the original file, with a .bak extension (it can be any extension you like) and theg
at the end of the sed expression tells sed to replace multiple copies on one line (rather than only the first one). The-print
to find is a convenience to show which files were being matched. All this depends on the exact versions of these tools on your system.您的意思是在 grep 匹配的所有文件中搜索并替换字符串吗?
编辑
因为这似乎是一个相当受欢迎的问题,我想更新一下。
现在我主要使用 ack-grep,因为它更加用户友好。 所以上面的命令是:
要处理文件名中的空格,您可以运行:
您可以使用 ack-grep 执行更多操作。 假设您只想将搜索限制为 HTML 文件:
如果空格不是问题,它会更短:
Do you mean search and replace a string in all files matched by grep?
Edit
Since this seems to be a fairly popular question thought I'd update.
Nowadays I mostly use
ack-grep
as it's more user-friendly. So the above command would be:To handle whitespace in file names you can run:
you can do more with
ack-grep
. Say you want to restrict the search to HTML files only:And if white space is not an issue it's even shorter:
如果您的
sed(1)
有-i
选项,请像这样使用它:如果没有,则根据您想要使用的语言,有以下几种方法的变体玩:
If your
sed(1)
has a-i
option, then use it like this:If not, there are several ways variations on the following depending on which language you want to play with:
我喜欢并使用上述解决方案或在数千个文件中进行系统范围的搜索和替换:
我假设使用“*.htm?” 它搜索并查找类似的 .htm 和 .html 文件,而不是 .html。
我将 .bak 替换为系统范围内更广泛使用的波形符 (~),以便更轻松地清理备份文件。
I like and used the above solution or a system wide search and replace among thousands of files:
I assume with the '*.htm?' instead of .html it searches and finds .htm and .html files alike.
I replace the .bak with the more system wide used tilde (~) to make clean up of backup files easier.
这可以使用 grep 来完成,而不需要使用 perl 或 find。
This works using grep without needing to use perl or find.
<代码>查找 . -type f -print0 | xargs -0将在每批加载一个解释器的同时处理多个包含空格的文件名。 快多了。
find . -type f -print0 | xargs -0 <sed/perl/ruby cmd>
will process multiple space contained file names at once loading one interpreter per batch. Much faster.的答案
已经给出使用 find 和 sed
find -name '*.html' -print -exec sed -i.bak 's/foo/bar/ g' {} \;
可能是标准答案。 或者您可以使用
perl -pi -es/foo/bar/g'
而不是sed
命令。对于大多数快速使用,您可能会发现命令 rpl 更容易记住。 这是替换 (foo -> bar),递归地替换当前目录中的所有文件:
rpl -R foo bar 。
默认情况下,大多数 Linux 发行版上不提供该功能,但安装起来很快 (
>apt-get install rpl
或类似的)。然而,对于涉及正则表达式和反向替换、文件重命名以及搜索和替换的更艰巨的工作,我所知道的最通用和最强大的工具是 repren,一个小型 Python 脚本我不久前写过一些棘手的重命名和重构任务。 您可能喜欢它的原因是:
查看自述文件以获取示例。
The answer already given of using find and sed
find -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;
is probably the standard answer. Or you could use
perl -pi -e s/foo/bar/g'
instead of thesed
command.For most quick uses, you may find the command rpl is easier to remember. Here is replacement (foo -> bar), recursively on all files in the current directory:
rpl -R foo bar .
It's not available by default on most Linux distros but is quick to install (
apt-get install rpl
or similar).However, for tougher jobs that involve regular expressions and back substitution, or file renames as well as search-and-replace, the most general and powerful tool I'm aware of is repren, a small Python script I wrote a while back for some thornier renaming and refactoring tasks. The reasons you might prefer it are:
Check the README for examples.
这实际上比看起来更容易。
Easy peasy。 如果您很好地掌握了 find、grep、xargs、sed 和 awk,那么在 bash 中进行文本文件操作几乎没有什么是不可能的:)
This is actually easier than it seems.
Easy peasy. If you get a good grasp on find, grep, xargs, sed, and awk, almost nothing is impossible when it comes to text file manipulation in bash :)
2022 年答案。
https: //github.com/BurntSushi/ripgrep/blob/master/FAQ.md#how-can-i-search-and-replace-with-ripgrep
将用 'bar' 替换所有 'foo' 实例ripgrep 在其中找到 foo 模式的文件。 sed 的 -i 标志表示您正在就地编辑文件,而 s/foo/bar/g 表示您正在执行模式 foo 对 bar 的替换,并且您正在全局执行此替换(所有出现的每个文件中的模式)。
2022 answer.
https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#how-can-i-search-and-replace-with-ripgrep
will replace all instances of 'foo' with 'bar' in the files in which ripgrep finds the foo pattern. The -i flag to sed indicates that you are editing files in place, and s/foo/bar/g says that you are performing a substitution of the pattern foo for bar, and that you are doing this substitution globally (all occurrences of the pattern in each file).