次のコードは、多くの行を含むファイルを読み取ります。ファイルの一部の行には 4 つの要素が含まれています。他の行には、最初の要素のみが含まれ、その後にタブで区切られた単一のスペースが含まれます (タブ区切りファイルです)。つまり、一部の行は「いっぱい」で、他の行は「空白」です。
このスクリプトのポイントは、データ ファイルを読み取り、空白行のインスタンスを見つけ、直前の行 (完全な行) を記憶し、スクロールして次の完全な行に到達するまで連続するすべての空白行を見つけることです。この一連の行 (直前の完全な行と直後の完全な行が隣接する連続した空白行) は、線形補間を適用して空白行を「埋める」サブルーチンによって使用されます。各セットの隣接実線の情報は、補間ステップで使用されます。このスクリプトは、以前に投稿された質問に対する回答であり、ユーザー @Kenosis から親切に提供されました。ここに複製されていますが、レイアウトにいくつかの非常に小さな変更があります---@Kenosisが最初に提案したほどきれいではありません. このやり取りはPerl で見ることができます。until 関数を使用する
#!/usr/bin/perl
use strict; use warnings;
die "usage: [ map positions file post SAS ]\n\n" unless @ARGV == 1;
my $mapfile = $ARGV[ 0 ];
open( my $FILE, "<$mapfile" );
my @file = <$FILE>;
for ( my $i = 1 ; $i < $#file ; $i++ ) # $#file returns the index of the last element in @file
{
if ( $file[$i] =~ /(?:\t\s){3}/ ) # if a blank line is found
{
print $file[ $i - 1 ]; # print preceding line
while ( $file[$i] =~ /(?:\t\s){3}/ and $i < $#file ) # keep printing so long as they are blank
# or end of file
{
#print $file[ $i++ ] # one-column, blank line
}
print $file[ $i ]; # print the succeeding full line
} # if
} # for
変更を挿入しようとすると問題が発生します。
my @collect = (); # array collects a current set of consecutive lines needed for linear interpolation
my @file = <$FILE>;
for ( my $i = 1 ; $i < $#file ; $i++ ) # $#file returns the index of the last element in @file
{
if ( $file[$i] =~ /(?:\t\s){3}/ ) # if a blank line is found
{
print $file[ $i - 1 ]; # print preceding line
push( @collect, $file[ $i - 1 ] );
while ( $file[$i] =~ /(?:\t\s){3}/ and $i < $#file ) # keep printing so long as they are blank
# or end of file
{
#print $file[ $i++ ]; # one-column, blank line
push( @collect, $file[ $i++ ] )
}
print $file[ $i ]; # else, succeeding full line
push( @collect, $file[ $i ] );
} # if
} # for
犯人は while ループにあります。push
そこにコマンドを追加すると、スクリプトの動作が変わります。スクリプトは、上記の最初のスクリプトのようにすべての行を出力しなくなりました。そのコマンドを追加すると、スクリプトの動作が変わるのはなぜですか?