我有一个看起来像的文件:
1
3
7
8
它的数字增加但不是以一致的方式:它是随机的。
我想要一个看起来像的文件:
1 1
2 0
3 1
4 0
5 0
6 0
7 1
8 1
它填写左侧列中缺少的数字,并添加\t1
以显示它存在于原始文件中(0表示缺席)。到目前为止,我有:
#! /usr/bin/perl
use warnings;
use strict;
my $infile = $ARGV[0];
open(IN, $infile) or die ("Could not open file.");
my $counter = 0;
while ( my $line = <IN> ) {
chomp $line;
if ( $counter == $line ) {
print "$line\t1\n";
++$counter;
}
else {
print "$counter\t0\n";
++$counter;
}
}
close (IN);
0 0
1 0
2 0
3 0
它不会产生所需的结果。有什么想法吗?
答案 0 :(得分:6)
您正在迭代输入文件的行,并且每次打印一行,因此您的输出只有输入的行数。
相反,你想要保留一个计数器(就像你一样),并且对于每一行,当该计数器小于该行上的数字时,打印$counter 0
,因为输入中不存在该数字:
#! /usr/bin/perl
use warnings;
use strict;
my $infile = $ARGV[0];
open (my $in, '<', $infile) or die ("Could not open file: $!.");
my $counter = 0;
while ( my $line = <$in> ) {
chomp $line;
while ( ++$counter < $line ) {
print "$counter\t0\n"
}
print "$line\t1\n" # or 'print "$counter\t1\n"', whichever you find clearer
}
close $in;
另请注意,我已使用3个参数打开,并使用词法变量$in
作为文件句柄而不是IN
,并且我已经包含{{1}在错误信息中,如果出现问题,你就会知道它是什么。
答案 1 :(得分:4)
这个Perl程序会按照您的要求执行。它从输入文件中读取每个数字,并为其前面没有输出的每个值打印一个零。然后它用一个打印输入值,然后从输入
读取下一个数字该程序期望输入文件的路径作为命令行上的参数并将输出打印到STDOUT
use strict;
use warnings 'all';
my $n = 1;
while ( <> ) {
my ($f) = split;
print $n++, "\t0\n" while $n < $f;
print $n++, "\t1\n";
}
1 1
2 0
3 1
4 0
5 0
6 0
7 1
8 1
答案 2 :(得分:2)
这样做的一种方法是添加第二个循环,在你匹配之前一直计算。
use strict;
use warnings;
my $counter = 1;
LINE: while( my $line = <DATA>) {
chomp $line;
while () {
if ($counter == $line) {
print "$counter\t1\n";
$counter++;
next LINE;
}
else {
print "$counter\t0\n";
$counter++;
}
}
}
__DATA__
1
3
7
8
这使用了无限循环while () { ... }
构造,以及外循环上的标签(LINE:
)和next LABEL
keyword,它们打破了离开内循环并跳转到带有标签的循环的下一次迭代。由于我们在比较后计算,我们需要从1
开始。