Perl:使用数组条目替换多个文件中的字符串

时间:2015-04-23 15:21:21

标签: arrays regex perl

我正在寻找一种简单的方法来替换多个文本文件中的字符串。在第一个文件中,字符串应该替换为数组@arrayF的第一个元素;在第二个文件中,字符串必须替换为第二个条目等。

我想替换;size=\d+\d+是任何数字的通配符。

这是我到目前为止所做的:

#!/usr/bin/perl -w

use strict;
use warnings;

my $counter = 0;
my @arrayF  = '/Users/majuss/Desktop/filelist.txt>';  # Reads all lines into array
my @files   = '/Users/majuss/Desktop/New_Folder/*'; #get Files into an array

foreach my $file ( @files ) {
  $file =~ s/;size=\d+/$arrayF[$counter]/g; #subst. 
  print
  $counter++; #increment array index
}

它返回零,没有任何反应。

我知道如何在单行中完成它,但我无法想出如何在那里实现数组。

2 个答案:

答案 0 :(得分:0)

  • 您没有打开filelist.txt并阅读它。

这样做你需要:

open ( my $input, "<", '/Users/majuss/Desktop/filelist.txt' ) or die $!;
my @arrayF = <$input>;
close ( $input );
  • 您需要使用glob来搜索这样的目录模式。

像这样:

foreach my $file ( glob ( '/Users/majuss/Desktop/New_Folder/*' ) {
      # stuff
}
  • 要在文件中进行搜索和替换,它实际上与单行内容有点不同。你可以在perlrun中查看“就地编辑” - 但这是perl试图伪装成sed的地方。我想你可以尝试一下 - perlvar中有一个选项:
  

$ ^ I   inplace-edit扩展的当前值。使用undef禁用就地编辑。   助记符:-i switch的值。

这个答案可能会提供一些见解: In-place editing of multiple files in a directory using Perl's diamond and in-place edit operator

相反,您可以:

foreach my $file ( glob  ( '/Users/majuss/Desktop/New_Folder/*' ) {
     open ( my $input_fh, "<", $file ) or die $!;
     open ( my $output_fh, ">", "$file.NEW" ) or die $!;
     my $replace = shift ( @arrayF );
     while ( my $line = <$input_fh> ) {
        $line =~ s/;size=\d+/$replace/g; 
        print {$output_fh} $line;
     }
     close ( $input_fh );
     close ( $output_fh );
      #rename 'output'. 
}

答案 1 :(得分:0)

请注意我在您的问题下评论的这些要点

  • 评论Reads all lines into array的行不会这样做。它只是将@arrayF设置为包含字符串/Users/majuss/Desktop/filelist.txt>的单元素列表。您可能需要打开该文件并将其内容读入数组

  • 评论get Files into an array的行不会这样做。它只是将@files设置为包含字符串/Users/majuss/Desktop/New_Folder/*的单元素列表。您可能需要使用glob将通配符扩展为文件列表

  • 声明

    $file =~ s/;size=\d+/$arrayF[$counter]/g
    

    正在尝试修改包含文件的名称的变量$file。大概你打算编辑那个文件的内容,所以你必须先打开并阅读它

  • 请不要在本地标识符中使用大写字母

  • 请勿在shebang行以及-w上使用use warnings;只是后者是正确的

这似乎可以满足您的要求,但要注意它是未经测试的,除非我已经检查过它会编译。请注意,您要备份原始文件,因为此代码将使用修改后的数据覆盖原始文件

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use autodie;

my $replacement_text = '/Users/majuss/Desktop/filelist.txt';
my $file_glob        = '/Users/majuss/Desktop/New_Folder/*';

my @replacement_text = do {
  open my $fh, '<', $replacement_text;
  <$fh>;
};
chomp @replacement_text;

my $i = 0;

for my $file ( glob $file_glob ) {

  my $contents = do {
    open my $in_fh, '<', $file;
    local $/;
    <$in_fh>;
  };

  $contents =~ s/;size=\d+/$replacement_text[$i]/g;

  open my $out_fh, '>', $file;
  print $out_fh $contents;

  ++$i;
}