Tek bir karakter (geleneksel uygulamalar gibi) veya normal ifade (beğen veya yap) olarak awkdavranılmasına bağlı olarak farklı yaklaşımlar uygulayabilirsiniz . Boş dosyalar da onları atlama eğilimi olarak kabul edilir .RSawkgawkmawkawk
gawk, mawkYa da diğer awkuygulamalar burada RSbir düzenli ifade olabilir.
Bu uygulamalarda ( mawkDebian gibi bazı işletim sistemlerinin @ThomasDickey tarafından sağlanan modern sürüm yerine çok eski bir sürüm gönderdiğine dikkat edin ), RStek bir karakter içeriyorsa, kayıt ayırıcı bu karakterdir veya boşken awkparagraf moduna girer RS, RSaksi halde normal ifade olarak davranır .
Buradaki çözüm, eşleştirilemeyen normal bir ifade kullanmaktır. Bazı gibi akla gelen x^ya da $x( xbaşlamadan önce veya bitiminden sonra). Ancak bazıları (özellikle birlikte gawk) diğerlerinden daha pahalıdır. Şimdiye kadar, ^$en verimli olanı buldum . Yalnızca boş bir girişle eşleşebilir, ancak daha sonra eşleşecek hiçbir şey olmaz.
Böylece yapabiliriz:
awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
Ancak bir uyarı, boş dosyaları atlamasıdır (aksine perl -0777 -n). Bu awk, kod ENDFILEyerine bir deyim koyarak GNU ile ele alınabilir . Ancak $0boş bir dosya işlendikten sonra sıfırlanmayacağından BEGINFILE ifadesinde de sıfırlamamız gerekir:
gawk -v RS='^$' '
BEGINFILE{$0 = ""}
ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
geleneksel awkuygulamalar, POSIXawk
Bunlarda, RSsadece bir karakterdir, değişkenleri yoktur BEGINFILE/ ENDFILE, RTdeğişkenleri yoktur, genellikle NUL karakterini işleyemezler.
Kullanmanın RS='\0'o zamandan beri çalışabileceğini düşünürsünüz, çünkü zaten NUL baytını içeren girdiyi işleyemezler, ancak hayır, RS='\0'geleneksel uygulamalarda RS=paragraf modu olan gibi davranılır .
Bir çözüm, girişte bulunma olasılığı düşük bir karakteri kullanmak olabilir \1. Çok baytlı karakter yerel ayarlarında, $'\U10FFFE'UTF-8 yerel ayarlarında olduğu gibi atanmamış veya karakter olmayan karakterler oluşturduğundan, gerçekleşmesi çok düşük olan bayt dizileri bile yapabilirsiniz . Gerçi gerçekten kusursuz değil ve boş dosyalarla da bir sorununuz var.
Başka bir çözüm, girdinin tamamını bir değişkende saklamak ve sonunda END deyiminde işlemek olabilir. Bu, aynı anda yalnızca bir dosyayı işleyebileceğiniz anlamına gelir:
awk '{content = content $0 RS}
END{$0 = content
printf "%s: <%s>\n", FILENAME, $0
}' file
Bu şuna eşittir sed:
sed '
:1
$!{
N;b1
}
...' file1
Bu yaklaşım ile bir diğer konu dosyasında yeni satır karakteriyle biten değildi (ve boş değildi) eğer biri hala keyfi eklenir olmasıdır $0ile (sonunda gawksen kullanarak bu geçici bir çözüm olur, RTyerine RSde yukarıdaki kod). Bunun bir avantajı, NR/ içindeki dosyadaki satır sayısının bir kaydına sahip olmanızdır FNR.