現在の行が入力ストリームの最後の行であるかどうかを判断する方法はありますか?
11 に答える
特殊なパターンは、すべての inputEND
の終了後にのみ一致します。このパターンは他のパターンと組み合わせることはできません。
おそらく、次の行にリセットして 1 を返す、または EOF の場合は 0 を返すgetline
疑似関数の方が便利です! $0
私はあなたが望むものだと思います。
例えば:
awk '{ if(getline == 0) { print "Found EOF"} }'
1 つのファイルのみを処理している場合、これは同等になります。
awk 'END { print "Found EOF" }'
選択肢が 2 つありますが、どちらも厄介です。
- 現在のすべての行のコピーを一時変数に格納し、END ブロックを使用してそれを処理します。
- システム コマンドを使用して BEGIN ブロックで "wc -l | getline" を実行し、ファイル内の行数を取得してから、その値をカウントアップします。
実行するには #2 を少しいじる必要があるかもしれませんが、うまくいくはずです。awkをやったのは久しぶりです。
これらは、あなたが望むことを行うための唯一の賢明な方法です。
awk 'NR==FNR{max++; next} FNR == max { print "Final line:",$0 }' file file
awk -v max="$(wc -l < file)" 'FNR == max { print "Final line:",$0 }' file
awk 'BEGIN{ while ( (getline dummy < ARGV[1]) > 0) max++; close(ARGV[1])} FNR == max { print "Final line:",$0 }' file
この「解決策」をどのように分類するかさえわかりません
{
t = lastline
lastline = $0
$0 = t
}
/test/ {
print "line <" $0 "> had a _test_"
}
END {
# now you have "lastline", it can't be processed with the above statements
# ...but you can work with it here
}
このハックのすばらしい点は、に割り当てること$0
で、残りのすべての宣言型パターンとアクションが機能し、1行遅れることです。上にEND
置いても、それらを機能させることはできませんが、最後の行を制御でき、他に何もしていません。END
引数リスト内の各ファイルの最後の行を検出するには、次のようにするとうまくいきます。
FNR == 1 || EOF {
print "last line (" FILENAME "): " $0
}
sed
簡単な方法の 1 つは、最終行以外のすべての行に 0 を配置し、最後の行に 1 を配置する中間スクリプトを介してファイルを実行することです。
cat input_file | sed 's/^/0/;$s/0/1/' | awk '{LST=/^1/;$0=substr($0,2)}
... your awk script in which you can use LST to check for the
... last line.'
あなたはこれを試すことができます:
awk 'BEGIN{PFNR=1} FNR==PFNR{PFNR++;next} {print FILENAME,PFNR=2} END{print FILENAME}' file1 file2
うーん、 awkEND
変数は、いつ到達したかを示しますEOF
。あまり参考にならないと思います
別の回答で述べたように、gawk 自体には BEGINFILE と ENDFILE がありますが、ポータブル ソリューションは gawk ユーザー マニュアルで提供されています。