Perl:删除空行并保存到新文件中

Perl:删除空行并保存到新文件中,perl,counter,erase,string,Perl,Counter,Erase,String,我正在尝试编写一个脚本,该脚本将计算并删除文件中的空行,并将更改保存到新文件中: 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) {

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

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);
if(@ARGV!=2){
打印“用法:$0填充输出文件\n”;
出口
}
$infle=@ARGV[0];
$outfile=@ARGV[1];
未结($old,“$outfile”);
@质量=;
foreach$newc(@mass){
$counter++;
如果($\=~/^$/){
打印“行号为$counter的$old中的空行\n”;
打印$new;
}
}
关闭(新);
接近($旧);

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

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

我会像这样编写循环代码

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


(<代码> $./COD>是当前输入行号).< /P> < p>在循环中不使用<代码> $NeC/<代码>,只打印空白行

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

如注释中所述,使用
$ARGV[0]
$ARGV[1]
$ARGV[0]
@ARGV
的第一个值,而
@ARGV[0]
是一个切片。有关更多详细信息,请参阅。

您的脚本应如下所示:

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);
if(@ARGV!=2){
打印“用法:$0填充输出文件\n”;
出口
}
$infle=$ARGV[0];
$outfile=$ARGV[1];
打开$old,“,$outfile;
@质量=;
$counter=0;
foreach$newc(@mass){
$counter++;
如果($newc=~/^$/){
打印“行号为$counter的$infle中的空行\n”;
}否则{#当不是空行时,在新文件中打印!
打印$new$newc;
}
}
关闭(新);
接近($旧);
如果(@ARGV!=2){
打印“用法:$0填充输出文件\n”;
出口
}
$infle=$ARGV[0];
$outfile=$ARGV[1];
开放式(旧,“$outfile”);
而($line=){
打印新的$line,除非($line=~/^$/);
}
关闭(新);
关闭(旧);
这里是另一个选项:

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";
    }
}
那就用

script.pl file.in >file.out
而不是

script.pl file.in file.out
但它也允许你做一些事情,比如

prog1 | script.pl | prog2

问题是什么?出了什么问题?@ARGV[0]运行良好,我以前在其他脚本中测试过。我的问题是,我无法删除输入文件
@array[$index]
的这些空行和空格,但这不是正确的样式
@array[…]
用于返回多个索引,如
my@slice=@array[1,2,3,4,5]
。请注意,符号匹配,
@slice
@array
以相同的字符开头。这就是为什么写
my$item=$array[0]
比写
my$item=@array[0]更好的原因为什么投反对票?代码有效!有人想推销他们的答案??否决投票的理由:(1)答案几乎没有任何解释。(2) 它使用了有点过时的编码风格;与当前最佳实践略有不同:(2.1)全局变量(2.2)忘记了
open
的返回值。(3) 解决方案仍然使用O(n)内存,其中O(1)就足够了。当然,不使用所有最佳实践的要点是尽量少地修改代码,这样他就可以看到修改的地方are@amon这与你的答案之间的区别是,OP可以看出他做错了什么。而在你的回答中,他只是知道你会怎么做。否决的理由:(1)答案没有解释。(2) 它使用了可怕和过时的编码风格;与当前的最佳实践相去甚远:(2.1)全局变量(2.2)裸字文件句柄(2.3)两个参数形式的
open
(2.4)忘记了
open
的返回值。这个原始问题是关于一个快速而肮脏的perl脚本。这不是一个生产应用程序,而是一个快速完成任务的工具。在10行脚本上遵循编码实践在我看来是愚蠢的。对每个人来说都是愚蠢的。@amon当我将这些规则应用于你的答案时,我也必须对你的答案投反对票。@OlafDietsche那么请尽一切努力。始终
使用strict;使用警告
,不管它是否是“…一个快速而肮脏的perl脚本”。必须承认这比其他脚本工作得更好,我在这里发布的其他代码中有一些bug!谢谢我希望您不介意我在您的答案中添加了一个部分,说明如何简化程序,使其更强大,同时表现得更像其他程序。@ikegami-mind?不,一点也不。我非常感谢您的添加和修改。我知道这对手术有好处,我也从中受益。谢谢你,他会记帐的<代码>/^$/
(不同于
/^\z/
)将匹配
“\n”
。顺便说一句,
chomp
可以替换为
-l
,因为
-nl
chomps。(同样适用于
-pl
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";
    }
}
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