我正在尝试搜索并替换linux机器上grep匹配的所有文件中的字符串.我有一些我想做的事情,但我不确定如何最好地将它们串在一起.
grep -n 'foo' *
会给我输出形式:
[filename]:[line number]:[text]
对于grep返回的每个文件,我想用"bar"替换"foo"并将结果写回文件.有没有一个好方法呢?也许是一个奇特的管道?
根据您给出的示例,这似乎是您想要的:
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
发现是一个方便,显示了正在匹配的文件.所有这些都取决于系统上这些工具的确切版本.
你的意思是搜索和替换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(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/' *
我喜欢并使用上述解决方案或系统范围的搜索并替换成千上万的文件:
find -name '*.htm?' -print -exec sed -i.bak 's/foo/bar/g' {} \;
我假设'*.htm?' 而不是.html它搜索并找到.htm和.html文件.
我用更多系统使用的波形符号(〜)替换.bak,以便更轻松地清理备份文件.