无法用Sed / Python / Perl替换给定文件夹内容中的单词

时间:2009-05-21 19:54:47

标签: python perl sed replace

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

我运行以下名为replace failedablefully

的Sed脚本
s/Masi/Bond/

在Zsh中

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

它为我提供了所有文件,也包括没有Masi的文件,作为输出。

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

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

5 个答案:

答案 0 :(得分: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代码

答案 1 :(得分:3)

为什么不将-i选项(man sed)传递给sed并完成它?如果它没有在文件中找到Masi,则只需重写该文件而不进行任何修改。或者我错过了什么?

如果您不想内联替换文件内容(-i将会这样做),您可以像现在一样完成,但抛出grep&amp;在它前面xargs

grep -rl Masi PATH/project/* | xargs sed -f PATH/replace

很多选项,但为此编写一个完整的perl脚本(我将给单行一个通行证;))。恕我直言,findgrepsedxargs等将更加灵活。

回应评论:

grep -rl Masi PATH/project/* | xargs sed -n -e '/Masi/ p'

答案 2 :(得分: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::Find(核心) - 遍历目录树。
  • File::Slurp - 有效阅读/撰写完整档案
  • File::Copy(核心) - 复制文件或文件句柄

答案 3 :(得分: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";
    }
  }
}

答案 4 :(得分: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)