Perl

應該從另一個文件中刪除一個文件行中的字元串的 perl 腳本的問題

  • September 21, 2015

我有一個文件~/foo和另一個文件~/remove.txt。我想編寫一個 perl 腳本,循環遍歷 的每一行並從中~/remove.txt刪除字元串的每個實例(其中的行在哪裡)。我的程式碼是(<LINE>)``~/foo``<LINE>``~/remove.txt

#! /usr/bin/perl 

use strict;
use warnings;

sub main
{
   my $infile  = "remove.txt";

   open(INPUT, $infile) or die "cannot open $infile";

   while(my $line = <INPUT>)
   {
   chomp($line);

   my $bad_string = "($line)";

   system( q( perl -p -i -e 's/$bad_string//g' foo ) );
   }

   close(INPUT);

}

main();

但是執行這個腳本似乎根本不會改變我的文件。我的腳本有什麼問題?

除了您要問的問題之外,您的腳本還有一個巨大的缺陷,即它使“remove.txt”中的每一行都完全通過“foo”。這是非常低效的。更好的方法是讀入’remove.txt’,構造一個長正則表達式,然後使用它來編輯’foo’。

最簡單的方法是將搜尋字元串推送到一個數組中,然後使用 ‘|’ ‘join()’ 數組 (regexp “or”) 字元來創建一個可以用作正則表達式的字元串。

這是一個執行此操作並修復您的原始問題的腳本。

#! /usr/bin/perl 

use strict;
use warnings;

# first construct a regular expression containing every
# line that needs to be removed.  This is so we only have
# to run a single pass through $infile rather than one
# pass per line in $removefile.
my @remove = ();

my $removefile='remove.txt';
open(REMFILE,"<",$removefile) || die "couldn't open $removefile: $!\n";
while(<REMFILE>) {
   chomp;
   next if (/^\s*$/);
   push @remove, $_;
};
close(REMFILE);

# choose one of the following two lines depending on
# whether you want to remove only entire lines or text
# within a line:
my $remove = '^(' . join("|",@remove) . ')$';
#my $remove = join("|",@remove);

# now remove the unwanted text from all lines in $infile
my $infile = 'foo';
system('perl','-p','-i','-e',"s/$remove//g",$infile);

# if you want to delete matching lines, try this instead:
#system('perl','-n','-i','-e',"print unless /$remove/",$infile);

引用自:https://unix.stackexchange.com/questions/230794