Sei*_*iti 12 perl search command-line replace bulk
我一直在尝试编写一个Perl脚本来替换我项目的所有源文件上的一些文本.我需要类似的东西:
perl -p -i.bak -e "s/thisgoesout/thisgoesin/gi" *.{cs,aspx,ascx}
Run Code Online (Sandbox Code Playgroud)
但是,它递归地解析目录的所有文件.
我刚刚开始编写脚本:
use File::Find::Rule;
use strict;
my @files = (File::Find::Rule->file()->name('*.cs','*.aspx','*.ascx')->in('.'));
foreach my $f (@files){
if ($f =~ s/thisgoesout/thisgoesin/gi) {
# In-place file editing, or something like that
}
}
Run Code Online (Sandbox Code Playgroud)
但是现在我被卡住了.有没有一种简单的方法来使用Perl编辑所有文件?
请注意,我不需要保留每个修改过的文件的副本; 我有他们所有的颠覆=)
更新:我在Cygwin上尝试过这个,
perl -p -i.bak -e "s/thisgoesout/thisgoesin/gi" {*,*/*,*/*/*}.{cs,aspx,ascx
Run Code Online (Sandbox Code Playgroud)
但看起来我的参数列表爆炸到允许的最大大小.事实上,我在Cygwin上遇到了很奇怪的错误......
eph*_*ent 13
如果@ARGV
在使用之前分配*ARGV
(也就是菱形<>
),$^I
/ -i
将处理这些文件而不是命令行中指定的文件.
use File::Find::Rule;
use strict;
@ARGV = (File::Find::Rule->file()->name('*.cs', '*.aspx', '*.ascx')->in('.'));
$^I = '.bak'; # or set `-i` in the #! line or on the command-line
while (<>) {
s/thisgoesout/thisgoesin/gi;
print;
}
Run Code Online (Sandbox Code Playgroud)
这应该完全符合你的要求.
如果您的模式可以跨越多行,请在undef $/;
之前添加一个,<>
以便Perl一次对整个文件进行操作,而不是逐行操作.
小智 7
您可能对File :: Transaction :: Atomic或File :: Transaction感兴趣
F :: T :: A的概要与您尝试的内容非常相似:
# In this example, we wish to replace
# the word 'foo' with the word 'bar' in several files,
# with no risk of ending up with the replacement done
# in some files but not in others.
use File::Transaction::Atomic;
my $ft = File::Transaction::Atomic->new;
eval {
foreach my $file (@list_of_file_names) {
$ft->linewise_rewrite($file, sub {
s#\bfoo\b#bar#g;
});
}
};
if ($@) {
$ft->revert;
die "update aborted: $@";
}
else {
$ft->commit;
}
Run Code Online (Sandbox Code Playgroud)
结合文件::发现你已经写过了,你应该好好去.
归档时间: |
|
查看次数: |
4198 次 |
最近记录: |