0

我有一个项目,其中有文件夹、子文件夹和文件。我需要在每个文件中用单词 Bond 替换单词 Masi。

我运行以下名为 replace 的 Sed 脚本失败

s/Masi/Bond/

在 Zsh 中

sed -f PATH/replace PATH2/project/**

它给了我所有的文件,也包括那些没有 Masi 的文件,作为输出。

Sed 不一定是完成这项任务的最佳工具。我对 Python 和 Perl 很感兴趣。

您将如何在 Sed/Perl/Python 中进行替换,以便仅更改文件内容?

4

5 回答 5

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 代码
于 2009-05-21T20:03:13.363 回答
3

为什么不直接将-i选项 ( man sed) 传递给 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'
于 2009-05-21T20:02:50.603 回答
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 );
   }
}
于 2009-05-21T20:30:43.010 回答
0

在 Windows 上测试的解决方案

需要 CPAN 模块 File::Slurp。将使用标准的 Unix shell 通配符。像 ./replace.pl PATH/replace.txt PATH2/replace*

#!/usr/bin/perl

use strict;
use warnings;
use File::Glob ':glob';
use File::Slurp;
foreach my $dir (@ARGV) {
  my @filelist = bsd_glob($dir);
  foreach my $file (@filelist) {
    next if -d $file;
    my $c=read_file($file);
    if ($c=~s/Masi/Bond/g) {
      print "replaced in $file\n";
      write_file($file,$c);
    } else {
      print "no match in $file\n";
    }
  }
}
于 2009-05-21T20:05:43.653 回答
0
import glob
import os

# Change the glob for different filename matching 
for filename in glob.glob("*"):
  dst=filename.replace("Masi","Bond")
  os.rename(filename, dst)
于 2009-06-02T18:52:01.547 回答