単一の文字(従来の実装のように)としてawk扱うか、正規表現(like またはdo)RSとして扱うかに応じて、異なるアプローチを取ることができます。空のファイルは、スキップする傾向があると見なされるのも難しいです。awkgawkmawkawk
gawk、mawkまたは正規表現になりうる他のawk実装RS。
これらの実装では(のためのmawkDebianのようないくつかのOSは非常に古いバージョンの代わりに、出荷することに注意してください、@ThomasDickeyによって維持近代的なものを)、あればRS単一の文字が含まれているレコードセパレータは、その文字である、またはawkとき段落モードに入りRS、空でありますRSそれ以外の場合は正規表現として扱います。
そこでの解決策は、一致する可能性のない正規表現を使用することです。x^または$x(x開始前、または終了後)のように思い浮かぶ人もいます。ただし、一部(特にgawk)は、他よりも高価です。これまでのところ、これが^$最も効率的な方法であることがわかりました。空の入力でのみ一致しますが、一致するものは何もありません。
できること:
awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
ただし、1つの注意点は、空のファイルをスキップすることです(とは反対perl -0777 -n)。代わりにステートメントにawkコードを入れることで、GNUで対処できますENDFILE。しかし$0、空のファイルを処理した後はリセットされないため、BEGINFILEステートメントでリセットする必要もあります。
gawk -v RS='^$' '
BEGINFILE{$0 = ""}
ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
従来のawk実装、POSIXawk
それらでRSは、たった1文字であり、BEGINFILE/ ENDFILEを持たず、RT変数を持たず、通常はNUL文字を処理できません。
RS='\0'とにかく、NULバイトを含む入力を処理できないため、using は機能すると考えられますが、いいえ、RS='\0'従来の実装ではRS=段落モードであるとして扱われます。
解決策の1つは、などの入力で検出されそうにない文字を使用することです\1。マルチバイト文字ロケールでは$'\U10FFFE'、UTF-8ロケールのように、割り当てられていない文字または非文字を形成するため、発生する可能性が非常に低いバイトシーケンスにすることもできます。しかし、絶対に万全ではなく、空のファイルにも問題があります。
別の解決策は、入力全体を変数に保存し、最後にENDステートメントで処理することです。ただし、一度に処理できるファイルは1つだけです。
awk '{content = content $0 RS}
END{$0 = content
printf "%s: <%s>\n", FILENAME, $0
}' file
それはに相当しsedます:
sed '
:1
$!{
N;b1
}
...' file1
そのアプローチの別の問題は、ファイルが改行文字で終わっていなかった場合(そして空ではなかった場合)、$0最後にまだ任意に追加されているgawkことです(で、RTではなくRS、上記のコード)。1つの利点は、ファイルの行数の記録がNR/にあることFNRです。