2

好的,所以我想删除文件中第一次出现的字符串,比如“dog”,并且只删除第一次出现。因此,如果文件读取:

狗很高兴。
狗喜欢跑。

输出将是

很高兴。
狗喜欢跑。

我有以下代码:

#!/usr/local/bin/perl

use warnings;
use strict;

my $file = $ARGV[0];
my $out = $ARGV[1];

open (IN, "<$file");
open (OUT, ">$out");
while(<IN>){
  s/dog/ /;
  print OUT $_;
}

close IN;
close OUT;

它可以工作,但不是只替换第一个实例,而是替换该单词的所有实例。我以为我必须使用全局修饰符 g 来使其替换所有实例?为什么它要替换我正在搜索的字符串的所有实例?这可能是我没有看到的一些简单错误。

4

3 回答 3

7

每次评估运算符时,它都会替换第一个实例,并为每一行评估运算符,因此您替换每行中的第一个实例。如果您使用/g,您将替换每一行中的所有实例。

my $seen;
while (<>) {
   ++$seen if !$seen && s/dog//;
   print;
}

或作为单行:

perl -pe'++$seen if !$seen && s/dog//;' infile >outfile

您可以重新添加文件句柄,但上面接受更标准和更灵活的用法。要获得与您的代码相同的效果,您只需使用

script.pl infile >outfile

代替

script.pl infile outfile
于 2012-07-16T14:44:00.873 回答
3

这可以通过单线来实现:

perl -0777 -pe 's/dog/ /' inputfile > outputfile

-0777开关会将文件作为单行读取,这将使您的替换按预期工作。这一行就相当于程序文件:

$/ = undef; 
$\ = undef;
while (<>) {
    s/dog/ /;
    print;
}
于 2012-07-16T15:16:12.450 回答
2
while ( <> ) { 
    my $found = s/dog//;
    print;
    last if $found;
}
print while <>;
于 2012-07-16T15:36:42.397 回答