คุณสามารถใช้วิธีการที่แตกต่างกันขึ้นอยู่กับว่าจะawkถือว่าRSเป็นตัวอักษรเดียว (เช่นawkการใช้งานแบบดั้งเดิมทำ) หรือการแสดงออกปกติ (เช่นgawkหรือmawkทำ) ไฟล์ที่ว่างเปล่านั้นมีความยุ่งยากที่จะถูกพิจารณาว่าawkมีแนวโน้มที่จะข้ามไป
gawk, mawkหรืออื่น ๆawkการใช้งานที่RSสามารถกับ regexp
ในการใช้งานเหล่านั้น (สำหรับmawkระวังว่า OS บางรุ่นเช่น Debian จัดส่งเวอร์ชันเก่ามากแทนที่จะเป็น modern ที่ดูแลโดย @ThomasDickey ) หากRSมีอักขระตัวเดียวตัวคั่นเร็กคอร์ดคืออักขระนั้นหรือawkเข้าสู่โหมดย่อหน้าเมื่อRSว่างเปล่า หรือถือว่าRSเป็นการแสดงออกปกติ
วิธีแก้ปัญหาคือใช้นิพจน์ทั่วไปที่ไม่สามารถจับคู่ได้ บางคนคิดเหมือนx^หรือ$x( xก่อนเริ่มหรือหลังจบ) อย่างไรก็ตามบางคน (โดยเฉพาะกับgawk) มีราคาแพงกว่าคนอื่น ๆ จนถึงตอนนี้ฉันพบว่า^$มีประสิทธิภาพมากที่สุด สามารถจับคู่กับอินพุตว่างเท่านั้น แต่จากนั้นจะไม่มีสิ่งใดเทียบได้
ดังนั้นเราสามารถทำ:
awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
หนึ่งข้อแม้คือว่ามันข้ามไฟล์เปล่า (ตรงกันข้ามperl -0777 -n) ที่สามารถแก้ไขได้ด้วย GNU awkโดยใส่รหัสลงในENDFILEคำสั่งแทน แต่เราจำเป็นต้องรีเซ็ต$0ในคำสั่ง BEGINFILE เพราะจะไม่ถูกรีเซ็ตหลังจากประมวลผลไฟล์ว่าง:
gawk -v RS='^$' '
BEGINFILE{$0 = ""}
ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
awkการใช้งานแบบดั้งเดิมPOSIXawk
ในนั้นRSเป็นเพียงหนึ่งตัวอักษรพวกเขาไม่มีBEGINFILE/ ENDFILEพวกเขาไม่มีRTตัวแปรพวกเขายังไม่สามารถประมวลผลอักขระ NUL ได้
คุณอาจคิดว่าการใช้RS='\0'งานสามารถใช้งานได้เนื่องจากไม่สามารถประมวลผลอินพุตที่มี NUL byte ได้ แต่ไม่ใช่ว่าRS='\0'ในการปรับใช้แบบดั้งเดิมจะได้รับการปฏิบัติเหมือนRS=ซึ่งเป็นโหมดย่อหน้า
\1ทางออกหนึ่งที่จะสามารถใช้ตัวอักษรที่ไม่น่าเป็นไปได้ที่จะพบในการป้อนข้อมูลเช่นที่ ในโลแคลอักขระหลายไบต์คุณสามารถทำให้เป็นลำดับไบต์ที่ไม่น่าจะเกิดขึ้นเนื่องจากเป็นอักขระที่ไม่ได้รับมอบหมายหรือไม่ใช่อักขระเช่น$'\U10FFFE'ในโลแคล UTF-8 ไม่เข้าใจผิดจริง ๆ แม้ว่าและคุณมีปัญหากับไฟล์ว่างเปล่าเช่นกัน
อีกวิธีหนึ่งคือการเก็บข้อมูลทั้งหมดในตัวแปรและดำเนินการในคำสั่ง END ที่สิ้นสุด ซึ่งหมายความว่าคุณสามารถประมวลผลได้ครั้งละหนึ่งไฟล์เท่านั้น:
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ใน รหัสด้านบน) ข้อดีอย่างหนึ่งคือการที่คุณจะมีบันทึกของจำนวนบรรทัดในไฟล์ในที่/NRFNR