18

while( <> )引数()として指定されたファイル./program 1.file 2.file 3.fileとUnixシステムの標準入力を処理する単純なプログラム。

それらを1つのファイルにまとめて、1行ずつ作業すると思います。問題は、最初のファイルで作業していることをどうやって知ることができるかということです。そして2番目のもので。

簡単な例として、ファイルの内容を1行で印刷したいと思います。

while( <> ){
    print "\n" if (it's the second file already);
    print $_;
}
4

3 に答える 3

21

ダイヤモンド演算子はファイルを連結せず、ファイルを開いて連続して読み取るだけです。これをどのように制御するかは、どのように制御する必要があるかによって異なります。ファイルの最後の行を読んだことを確認する簡単な方法は、次を使用すること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;
}
于 2013-02-17T15:24:58.977 に答える
12

これ<>は、readline演算子の特殊なケースです。通常、ファイルハンドルが必要です<$fh>

ファイルハンドルが省略されている場合は、魔法のARGVファイルハンドルが使用されます。

コマンドライン引数が指定されていない場合は、ARGVですSTDIN。コマンドライン引数が指定されている場合は、それらのそれぞれに順番ARGVopenedされます。これはに似ています

# 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 * |はあなたが望むことをしないかもしれません。

于 2013-02-17T15:08:41.950 に答える
2

の現在のファイルの名前は、<>特別な$ARGV 変数に含まれています。

@ARGVパラメータ配列のファイルのリストを現在のファイル名と照合して、リスト内のファイルの位置を取得できます。期待するパラメータがファイル名だけであると仮定すると、次のように簡単に実行できます。

my %filename_positions = map { ( $ARGV[$_] => $_ ) } 0..$#ARGV;

while (<>) {
    my $file_number = $filename_positions{$ARGV};
    #... if ($file_number == 0) { #first file     
}
于 2013-02-17T15:08:58.447 に答える