while( <> )
を使用した単純なプログラムは、引数として指定されたファイルを処理します(./program 1.file 2.file 3.file
)およびUnixシステムの標準入力。
それらを1つのファイルに連結し、行ごとに作業すると思います。問題は、最初のファイルで作業していることをどのようにして知るのですか?そして、2番目のもの。
簡単な例として、ファイルのコンテンツを1行で印刷します。
while( <> ){
print "\n" if (it's the second file already);
print $_;
}
ダイアモンド演算子はファイルを連結せず、単に開いて連続して読み取ります。これをどのように制御するかは、どのように制御する必要があるかによって異なります。ファイルの最後の行を読んだことを確認する簡単な方法は、eof
を使用することです:
while (<>) {
chomp; # remove newline
print; # print the line
print "\n" if eof; # at end of file, print a newline
}
また、処理中の順序でどのファイルを追跡するカウンターを考慮することもできます
$counter++ if eof;
このカウントは、ファイルの最終行で1つずつ増加するため、時期尚早に使用しないでください。
行番号を追跡したい場合$.
現在のファイルハンドルで、close
ARGVファイルハンドルを使用して、このカウンターをリセットできます。
while (<>) {
print "line $. : ", $_;
close ARGV if eof;
}
<>
はreadline演算子の特殊なケースです。通常、ファイルハンドルを取ります:<$fh>
。
ファイルハンドルが省略されている場合、マジックARGV
ファイルハンドルが使用されます。
コマンドライン引数が指定されていない場合、ARGV
はSTDIN
です。コマンドライン引数が指定されている場合、ARGV
はそれぞれ順にopen
edされます。これは
# Pseudocode
while ($ARGV = shift @ARGV) {
open ARGV, $ARGV or do{
warn "Can't open $ARGV: $!";
next;
};
while (<ARGV>) {
...; # your code
}
}
$ARGV
変数は実数で、現在開いているファイルのファイル名を保持します。
open
の2つの引数形式(おそらく舞台裏でここで使用される)は非常に安全ではないことに注意してください。ファイル名rm -rf * |
はあなたが望むことをしないかもしれません。
<>
の現在のファイルの名前は、特別な$ARGV
変数 に含まれています。
@ARGV
パラメーター配列からのファイルのリストを現在のファイル名と相互一致させて、リスト内のファイルの位置を取得できます。予想されるパラメータがファイル名のみであると仮定すると、次のことが簡単にできます。
my %filename_positions = map { ( $ARGV[$_] => $_ ) } 0..$#ARGV;
while (<>) {
my $file_number = $filename_positions{$ARGV};
#... if ($file_number == 0) { #first file
}