Anda dapat mengambil pendekatan berbeda tergantung pada apakah awkmemperlakukan RSsebagai karakter tunggal (seperti awkimplementasi tradisional lakukan) atau sebagai ekspresi reguler (suka gawkatau mawktidak). File kosong juga rumit untuk dipertimbangkan karena awkcenderung melompati mereka.
gawk, mawkatau awkimplementasi lain di mana RSbisa menjadi regexp.
Dalam implementasi tersebut (untuk mawk, berhati-hatilah bahwa beberapa OS seperti Debian mengirimkan versi yang sangat lama dan bukan versi modern yang dikelola oleh @ThomasDickey ), jika RSberisi satu karakter, pemisah rekaman adalah karakter itu, atau awkmemasuki mode paragraf ketika RSkosong, atau memperlakukan RSsebagai ekspresi reguler jika tidak.
Solusinya adalah menggunakan ekspresi reguler yang tidak mungkin dapat dicocokkan. Beberapa muncul di pikiran seperti x^atau $x( xsebelum memulai, atau setelah akhir). Namun beberapa (terutama dengan gawk) lebih mahal daripada yang lain. Sejauh ini, saya telah menemukan itu ^$yang paling efisien. Itu hanya bisa cocok dengan input kosong, tetapi kemudian tidak akan ada yang cocok dengan.
Jadi kita bisa melakukan:
awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
Satu peringatan adalah bahwa ia melewatkan file kosong (bertentangan dengan perl -0777 -n). Itu bisa diatasi dengan GNU awkdengan memasukkan kode dalam ENDFILEpernyataan sebagai gantinya. Tetapi kita juga perlu mengatur ulang $0dalam pernyataan BEGINFILE karena jika tidak maka tidak akan diatur ulang setelah memproses file kosong:
gawk -v RS='^$' '
BEGINFILE{$0 = ""}
ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
awkimplementasi tradisional , POSIXawk
Pada mereka, RShanya satu karakter, mereka tidak memiliki BEGINFILE/ ENDFILE, mereka tidak memiliki RTvariabel, mereka juga umumnya tidak dapat memproses karakter NUL.
Anda akan berpikir bahwa menggunakan RS='\0'bisa bekerja maka karena bagaimanapun mereka tidak dapat memproses input yang berisi byte NUL, tetapi tidak, yang RS='\0'dalam implementasi tradisional diperlakukan sebagai RS=, yang merupakan mode paragraf.
Salah satu solusinya adalah menggunakan karakter yang tidak mungkin ditemukan di input seperti \1. Di lokal karakter multibyte, Anda bahkan dapat membuatnya byte-sequence yang sangat tidak mungkin terjadi karena mereka membentuk karakter yang tidak ditugaskan atau non-karakter seperti $'\U10FFFE'di lokal UTF-8. Tidak terlalu mudah dan Anda memiliki masalah dengan file kosong juga.
Solusi lain dapat menyimpan seluruh input dalam suatu variabel dan memprosesnya dalam pernyataan AKHIR di bagian akhir. Itu berarti Anda hanya dapat memproses satu file pada satu waktu:
awk '{content = content $0 RS}
END{$0 = content
printf "%s: <%s>\n", FILENAME, $0
}' file
Itu setara seddengan:
sed '
:1
$!{
N;b1
}
...' file1
Masalah lain dengan pendekatan itu adalah bahwa jika file tidak berakhir dengan karakter baris baru (dan tidak kosong), orang masih secara sewenang-wenang ditambahkan di $0akhir (dengan gawk, Anda akan mengatasinya dengan menggunakan RTalih-alih RSdi kode di atas). Satu keuntungan adalah bahwa Anda memiliki catatan jumlah baris dalam file di NR/ FNR.