1

我正在尝试编写一个脚本,该脚本将计算并删除文件中的空行并将更改保存在新文件中:

if (@ARGV != 2) {
  print "Usage: $0 infile outfile\n";
  exit;
}
$infile = @ARGV[0];
$outfile = @ARGV[1];
open($old, "<$infile");
open($new, ">$outfile");
@mass = <$old>;
foreach $newc(@mass) {
    $counter++;
    if ($_ =~ /^$/) {
        print "blank line found in $old at line number $counter\n";
        print $new;
    }
}
close($new);
close($old);

但它不起作用。我哪里错了?

4

5 回答 5

4

这是另一种选择:

use strict;
use warnings;

@ARGV == 2 or die "Usage: $0 infile outfile\n";

open my $fhIN,  '<', $ARGV[0] or die $!;
open my $fhOUT, '>', $ARGV[1] or die $!;

while (<$fhIN>) {
    if (/\S/) {
        print $fhOUT $_;
    }
    else {
        print "Blank at line $.\n";
    }
}

正如amon所示,您可以迭代文件的行,而无需先将它们读入数组。该脚本还利用了$.,其中包含文件的当前行号。正则表达式/\S/检查行中的任何非空白字符,因为这表示非空白行。如果/\S/为真,则将行写入outfile,否则打印空行通知。

文件句柄的词法范围为(首选方法)的三参数形式open,因此文件将自动close在脚本末尾。


您甚至可以更进一步,利用 STDIN、STDOUT 和 STDERR 获得最大的灵活性和实用性。

use strict;
use warnings;

while (<>) {
    if (/\S/) {
        print;
    }
    else {
        print STDERRR "Blank at line $.\n";
    }
}

然后只需使用

script.pl file.in >file.out

代替

script.pl file.in file.out

但它也允许你做类似的事情

prog1 | script.pl | prog2
于 2013-01-16T20:09:27.590 回答
2

您不在$newc循环中使用,并且只打印空行

foreach $newc (@mass) {
    $counter++;
    if ($newc =~ /^$/) {
        print "blank line found in $old at line number $counter\n";
    } else {
        print $new $newc;
    }
}

正如评论中已经指出的那样,使用$ARGV[0]and $ARGV[1]$ARGV[0]是 的第一个值@ARGV,而@ARGV[0]是切片。有关更多详细信息,请参阅切片

于 2013-01-16T19:01:55.363 回答
1

中的行@mass仍然包含一个尾随换行符。在您的正则表达式中考虑这一点,或者选择这些值。

我会像这样对循环进行编码

while (<$old>) {
  chomp;
  say {$new} $_ if length;
}

另外,测试 open 的返回值:

open my $old, "<", $infile or die qq(Can't open "$infile": $!);

整个代码作为一个单行代码:

perl -nE'chomp; say if length' infile.txt >outfile.txt

或者

perl -nE'chomp; if(length){say}else{say STDERR "blank on line $."}' infile.txt >outfile.txt

$.是当前输入的行号。)

于 2013-01-16T19:00:15.937 回答
-2

你的脚本应该是这样的:

if (@ARGV != 2) {
  print "Usage: $0 infile outfile\n";
  exit;
}
$infile = $ARGV[0];
$outfile = $ARGV[1];
open $old, "<", $infile;
open $new, ">", $outfile;
@mass = <$old>;
$counter = 0;
foreach $newc (@mass) {
    $counter++;
    if ($newc =~ /^$/) {
        print "blank line found in $infile at line number $counter\n";
    } else { # print in the new file when not an empty line!
        print $new $newc;
    }
}
close($new);
close($old);
于 2013-01-16T19:04:12.777 回答
-2
if (@ARGV != 2) {
  print "Usage: $0 infile outfile\n";
  exit;
}

$infile = $ARGV[0];
$outfile = $ARGV[1];
open(OLD, "<$infile");
open(NEW, ">$outfile");
while ($line = <OLD>) {
    print NEW $line unless ($line =~ /^$/);
}
close(NEW);
close(OLD);
于 2013-01-16T19:06:22.207 回答