我正在尝试搜索和替换grep匹配的所有文件中的字符串:
grep -n 'foo' *
将以以下形式给我输出:
[filename]:[line number]:[text]
对于通过的grep返回每个文件,我想通过替换,修改文件foo
有bar
。
我正在尝试搜索和替换grep匹配的所有文件中的字符串:
grep -n 'foo' *
将以以下形式给我输出:
[filename]:[line number]:[text]
对于通过的grep返回每个文件,我想通过替换,修改文件foo
有bar
。
Answers:
您的意思是搜索并替换所有与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
根据您提供的示例,这似乎是您想要的:
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
发现是一个方便的表演哪些文件被被匹配。所有这些取决于系统上这些工具的确切版本。
find
命令提供一个目录,例如从find . -name '*.html'
或find directoryname/ -name '*'
。
sed -ie 's/foo/bar/g' *
如果您sed(1)
可以-i
选择,请按以下方式使用它:
for i in *; do
sed -i 's/foo/bar/' $i
done
如果没有,则根据您要使用的语言,有以下几种变种:
ruby -i.bak -pe 'sub(%r{foo}, 'bar')' *
perl -pi.bak -e 's/foo/bar/' *
for i in *; do ...
sed是多余的,sed可以将文件列表作为参数。
for i in *; do; sed -i 's/foo/bar/g' "$i"; done
使用grep可以工作,而无需使用perl或find。
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
-i
不适用于其他操作系统。在ubuntu上为我工作。
xargs
联机帮助页(在Ubuntu上)说-i
已弃用,请-I
改用。因此,我们应该说:grep -rli 'old-word' * | xargs -I filepath sed -i 's/old-word/new-word/g' filepath
find . -type f -print0 | xargs -0 <sed/perl/ruby cmd>
将立即处理多个空间包含的文件名,每批加载一个解释器。快多了。
使用find和sed已经给出的答案
find -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;
这可能是标准答案。或者您可以使用perl -pi -e s/foo/bar/g'
代替sed
命令。
对于大多数快速使用,您可能会发现命令rpl更容易记住。这是当前目录中所有文件的递归替换(foo-> bar):
rpl -R foo bar .
在大多数Linux发行版中,默认情况下它不可用,但是可以快速安装(apt-get install rpl
或类似版本)。
但是,对于涉及正则表达式和后向替换,文件重命名以及搜索和替换的艰巨工作,我知道最通用,最强大的工具是repren,这是我为一些代码编写的一个小型Python脚本棘手的重命名和重构任务。您可能更喜欢的原因是:
查看自述文件中的示例。
这实际上比看起来容易。
grep -Rl 'foo' ./ | xargs -n 1 -I % sh -c "ls %; sed -i 's/foo/bar/g' %";
十分简单。如果您对find,grep,xargs,sed和awk有了很好的了解,那么在bash中进行文本文件操作时几乎没有什么不可能的:)
Can't open Untitled: No such file or directory, <> line 5
尝试“无标题的文件夹/file.txt”时。