【问题标题】:How can I do bulk search and replace with Perl?如何使用 Perl 进行批量搜索和替换?
【发布时间】:2010-10-29 10:07:41
【问题描述】:

我有以下脚本,它接受输入文件、输出文件和 用其他字符串替换输入文件中的字符串并写出 输出文件。

我想更改脚本以遍历文件目录 即脚本不应提示输入和输出文件,而应采用 作为参数的目录路径,例如 C:\temp\allFilesTobeReplaced\ 和 搜索字符串 x 并用 y 替换它下的所有文件 目录路径并写出相同的文件。

我该怎么做?

谢谢。

$file=$ARGV[0];

open(INFO,$file);
@lines=<INFO>;
print @lines;

open(INFO,">c:/filelist.txt");

foreach $file (@lines){
   #print "$file\n";
   print INFO "$file";
}

#print "Input file name: ";
#chomp($infilename = <STDIN>);

if ($ARGV[0]){
   $file= $ARGV[0]
}

print "Output file name: ";
chomp($outfilename = <STDIN>);
print "Search string: ";
chomp($search = <STDIN>);
print "Replacement string: ";
chomp($replace = <STDIN>);

open(INFO,$file);
@lines=<INFO>;
open(OUT,">$outfilename") || die "cannot create $outfilename: $!";

foreach $file (@lines){    
    # read a line from file IN into $_
    s/$search/$replace/g; # change the lines
    print OUT $_; # print that line to file OUT
}
close(IN);
close(OUT);

【问题讨论】:

    标签: perl replace bulk


    【解决方案1】:

    perl单行的使用

    perl -pi -e 's/original string/new string/' filename
    

    可以与File::Find 结合,给出以下单个脚本(这是我用于许多此类操作的模板)。

    use File::Find;
    
    # search for files down a directory hierarchy ('.' taken for this example)
    find(\&wanted, ".");
    
    sub wanted
    {
        if (-f $_)
        {
            # for the files we are interested in call edit_file().
            edit_file($_);
        }
    }
    
    sub edit_file
    {
        my ($filename) = @_;
    
        # you can re-create the one-liner above by localizing @ARGV as the list of
        # files the <> will process, and localizing $^I as the name of the backup file.
        local (@ARGV) = ($filename);
        local($^I) = '.bak';
    
        while (<>)
        {
            s/original string/new string/g;
        }
        continue
        {
            print;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用 -i 参数来做到这一点:

      照常处理所有文件,但包括 -i.bak:

      #!/usr/bin/perl -i.bak
      
      while ( <> ) {
         s/before/after/;
         print;
      }
      

      这应该处理每个文件,并将原始文件重命名为 original.bak 当然,您可以像@Jamie Cook 提到的那样将其作为单行来完成

      【讨论】:

        【解决方案3】:

        试试这个

        #!/usr/bin/perl -w
        
        @files = <*>;
        foreach $file (@files) {
          print $file . '\n';
        }
        

        看看 Perl 中的 glob:

        【讨论】:

          【解决方案4】:

          我知道您可以从命令行使用简单的 Perl 单行程序,其中文件名可以是单个文件名或文件名列表。您可能可以将此与 bgy 的答案结合起来以获得所需的效果:

          perl -pi -e 's/original string/new string/' filename
          

          我知道这很陈词滥调,但这听起来很像 sed,如果你可以使用 gnu 工具的话:

          for i in `find ./allFilesTobeReplaced`; do sed -i s/original string/new string/g $i; done
          

          【讨论】:

            【解决方案5】:

            perl -pi -e 's#OLD#NEW#g' 文件名。 您可以将文件名替换为适合您的文件列表的模式。

            【讨论】:

              猜你喜欢
              • 2017-01-05
              • 1970-01-01
              • 2013-05-20
              • 2013-04-06
              • 1970-01-01
              • 2012-01-03
              • 2021-01-31
              • 2019-05-05
              • 1970-01-01
              相关资源
              最近更新 更多