当前位置:  开发笔记 > 编程语言 > 正文

是否有一种简单的方法来进行批量文件文本替换?

如何解决《是否有一种简单的方法来进行批量文件文本替换?》经验,为你挑选了3个好方法。

我一直在尝试编写一个Perl脚本来替换我项目的所有源文件上的一些文本.我需要类似的东西:

perl -p -i.bak -e "s/thisgoesout/thisgoesin/gi" *.{cs,aspx,ascx}

但是,它递归地解析目录的所有文件.

我刚刚开始编写脚本:

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
    }
}

但是现在我被卡住了.有没有一种简单的方法来使用Perl编辑所有文件?

请注意,我不需要保留每个修改过的文件的副本; 我有他们所有的颠覆=)

更新:我在Cygwin上尝试过这个,

perl -p -i.bak -e "s/thisgoesout/thisgoesin/gi" {*,*/*,*/*/*}.{cs,aspx,ascx

但看起来我的参数列表爆炸到允许的最大大小.事实上,我在Cygwin上遇到了很奇怪的错误......



1> ephemient..:

如果@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;
}

这应该完全符合你的要求.

如果您的模式可以跨越多行,请在undef $/;之前添加一个,<>以便Perl一次对整个文件进行操作,而不是逐行操作.



2> 小智..:

您可能对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;
  }

结合文件::发现你已经写过了,你应该好好去.



3> Svante..:

您可以使用Tie :: File来可伸缩地访问大文件并在适当的位置更改它们.请参阅联机帮助页(man 3perl Tie :: File).

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有