Arrays Perl:用数组项替换多个文件中的字符串

Arrays Perl:用数组项替换多个文件中的字符串,arrays,regex,perl,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>'; # Read

我正在寻找一种简单的方法来替换多个文本文件中的字符串。在第一个文件中,字符串应替换为数组的第一个元素
@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
}
它返回零,什么也没发生

我知道如何在一行程序中实现它,但我想不出如何在那里实现阵列。

  • 您没有打开并阅读
    filelist.txt
要做到这一点,您需要:

open ( my $input, "<", '/Users/majuss/Desktop/filelist.txt' ) or die $!;
my @arrayF = <$input>;
close ( $input );
  • 在一个文件中搜索和替换,实际上与一行程序有点不同。您可以在中查看“就地编辑”,但这正是perl试图伪装成
    sed
    的地方。我认为,如果您尝试,您可以做到这一点-有一个选项:
$^I 就地编辑扩展名的当前值。使用undef禁用就地编辑。 助记符:i开关的值

这个答案可能会给我们一些启示:

相反,您可以:

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'. 
}
foreach my$文件(glob('/Users/majuss/Desktop/New_Folder/*')){
打开(my$input_fh,“,“$file.NEW”)或死亡$!;
my$replace=shift(@arrayF);
while(我的$line=){
$line=~s/;size=\d+/$replace/g;
打印{$output_fh}$行;
}
关闭($input\U fh);
关闭($output_fh);
#重命名“输出”。
}

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

  • 注释的
    行将所有行读取到数组中
    不会这样做。它只是将
    @arrayF
    设置为一个元素列表,其中包含字符串
    /Users/majuss/Desktop/filelist.txt>
    。您可能需要打开文件并将其内容读取到数组中

  • 注释行
    将文件放入数组
    不会这样做。它只是将
    @Files
    设置为一个元素列表,其中包含字符串
    /Users/majuss/Desktop/New_Folder/*
    。您可能需要使用
    glob
    将通配符扩展为文件列表

  • 声明

    $file =~ s/;size=\d+/$arrayF[$counter]/g
    
    正在尝试修改变量
    $file
    ,该变量包含文件名。您可能想编辑该文件的内容,因此必须先打开并读取该文件

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

  • 不要在shebang行中使用
    -w
    ,也不要使用
    警告
    ;只有后者是正确的

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

#!/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;
}
!/usr/bin/perl
严格使用;
使用警告;
使用5.010;
使用自动模具;
my$replacement_text='/Users/majuss/Desktop/filelist.txt';
我的$file_glob='/Users/majuss/Desktop/New_Folder/*';
我的@replacement_text=do{
打开我的$fh、、$文件;
打印$out\u fh$内容;
++$i;
}

您可能希望在最后使用选项/ge,而不仅仅是/g。请参阅perldoc perlreYour'@files'没有扩展模式。您需要
my@files=glob('/Users/majuss/Desktop/New_Folder/*'))
您也没有打开或读取“filelist.txt”-您需要使用
打开
。注释行
将所有行读入数组
将文件读入数组
没有这样做。您需要在第一种情况下打开文件并读取它,在第二种情况下使用
全局
。此外,请不要使用上ca使用本地标识符中的字母,不要在shebang行中使用
-w
,也不要使用
警告
;如果您有
-w
开关,则后者是正确的,您不需要
使用警告
(反之亦然);它们做同样的事情。如果每行只有一个
;size=
字符串,您就不需要正则表达式上的
/g
。否则,正如其他人所指出的,您不会读取文件列表或读取每个文件,也不会真正执行您计划执行的任何操作。:-)@mwp:鉴于OP的代码根本不做任何文件IO,我认为你的评论是多余的。您的参数在第一行是错误的,我认为您需要在内部while循环之前设置
$replace
(每个文件一个值)。您的正则表达式上的
/g
是多余的。我认为您的
do
中缺少一个
来设置
@file\u列表
。我想你想在最后打印{$out\u fh}$contents
$out\u fh->print($contents)
。正如我在其他地方指出的,
/g
是多余的。@mwp:谢谢。我同意读取丢失的文件,但我的
print$out\u fh$contents
没有问题,如果文件库中多次出现该模式,则需要使用
/g
修饰符。如果不期望多次出现,那么在计算上是浪费的,但这可能是OP在这个时候遇到的最小问题。
#!/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;
}