无法使用Sed/Python/Perl替换文件夹内容中的单词
我有一个项目,里面有文件夹、子文件夹和文件。我需要把每个文件里的“ Masi”这个词替换成“ Bond”。
我运行了一个叫做replace的Sed脚本,但没有成功。
s/Masi/Bond/
是在Zsh中运行的。
sed -f PATH/replace PATH2/project/**
这个脚本的输出给了我所有的文件,包括那些没有“Masi”的文件。
Sed可能不是做这个任务的最佳工具。我对Python和Perl比较感兴趣。
你会怎么用Sed/Perl/Python来进行替换,确保只改变文件的内容呢?
5 个回答
3
重命名一个装满文件的文件夹:
use warnings;
use strict;
use File::Find::Rule;
my @list = File::Find::Rule->new()->name(qr/Masi/)->file->in('./');
for( @list ){
my $old = $_;
my $new = $_;
$new =~ s/Masi/Bond/g;
rename $old , $new ;
}
在文件中替换字符串
use warnings;
use strict;
use File::Find::Rule;
use File::Slurp;
use File::Copy;
my @list = File::Find::Rule->new()->name("*.something")->file->grep(qr/Masi/)->in('./');
for( @list ){
my $c = read_file( $_ );
if ( $c =~ s/Masi/Bond/g; ){
File::Copy::copy($_, "$_.bak"); # backup.
write_file( $_ , $c );
}
}
- strict (核心) - Perl中的一种设置,用来限制不安全的写法
- warnings (核心) - Perl中的一种设置,用来控制可选的警告信息
- File::Find::Rule - 一种用于查找文件的替代接口
- File::Find (核心) - 用来遍历文件夹树的工具
- File::Slurp - 高效地读取和写入完整文件
- File::Copy (核心) - 用来复制文件或文件句柄的工具
3
为什么不直接给sed加上-i这个选项(可以通过man sed查看说明)就解决问题呢?如果它在文件里找不到Masi,文件就会被重新写一遍,但内容不会变。难道我有什么没理解的吗?
如果你不想直接在文件里替换内容(这就是-i的作用),你可以像现在这样做,但在前面加上grep和xargs:
grep -rl Masi PATH/project/* | xargs sed -f PATH/replace
有很多选择,但不要为这个写一个完整的perl脚本(我会放过那种一行代码的写法;))。find、grep、sed、xargs等等,个人认为总是更灵活。
针对评论的回复:
grep -rl Masi PATH/project/* | xargs sed -n -e '/Masi/ p'
12
在当前目录及其子目录中替换所有文件里的某个词
perl -p -i -e 's/Masi/Bond/g' $(grep -rl Masi *)
如果文件名中有空格,上面的命令可能会失效。更安全的做法是:
find . -type f -exec perl -p -i -e 's/Masi/Bond/g' {} \;
或者在Mac上,如果文件名中有空格
find . -type f -print0 | xargs -0 perl -p -i -e 's/Masi/Bond/g'
解释
- -p的意思是打印输出或者出错时停止
- -i的意思是“不要创建任何备份文件”
- -e允许你在命令行中运行perl代码