使用
perl -pi -e 's/pattern/replacement/g' $(find src -type f)
很好,除了一件事:所有文件都被覆盖,即使是那些没有任何匹配的文件。这并不好,因为我经常在Emacs或Eclipse中打开它们,然后问我无聊的问题。有一种简单的方法可以防止触摸未更改的文件(在查找中使用grep的工作量太大,特别是对于复杂的模式)。
答案 0 :(得分:4)
不是将每个文件传递给perl进行处理,而是自己预先选择它们。
查找其中包含pattern
的文件:
grep -Plr 'pattern' src
然后使用它代替find
调用:
perl -pi -e 's/pattern/replacement/g' $(grep -Plr pattern src)
或者甚至喜欢这样:
grep -Plr 'pattern' src | xargs perl -pi -e's/pattern/replacement/g'
这也可能更快,因为你没有不必要地处理文件。
答案 1 :(得分:4)
打开文件后-i
的第一件事就是unlink
,这意味着你不能对你不想修改的文件使用-i
。< / p>
find src -type f -exec grep -Pl 'pattern' {} + |
xargs perl -i -pe's/pattern/replacement/g'
当然,grep
已经可以执行递归搜索,因此除非您需要使用find
来过滤结果,否则您可以使用
grep -Plr 'pattern' src |
xargs perl -i -pe's/pattern/replacement/g'
注意:cmd | xargs perl ...
可以处理的文件多于perl ... $( cmd )
。
答案 2 :(得分:2)
-p
导致Perl在程序周围采用以下循环,这使得它迭代文件名参数,有点像sed:
LINE: while (<>) { ... # your program goes here } continue { print or die "-p destination: $!\n"; }
-i [延伸]
相当于
#!/usr/bin/perl $extension = '.orig'; LINE: while (<>) { if ($ARGV ne $oldargv) { if ($extension !~ /\*/) { $backup = $ARGV . $extension; } else { ($backup = $extension) =~ s/\*/$ARGV/g; } rename($ARGV, $backup); open(ARGVOUT, ">$ARGV"); select(ARGVOUT); $oldargv = $ARGV; } s/foo/bar/; } continue { print; # this prints to original filename } select(STDOUT);
现在,这意味着您可以使用此骨架脚本,并在未进行替换的情况下修改还原备份。