คุณสามารถใช้วิธีการที่แตกต่างกันขึ้นอยู่กับว่าจะ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
ใน รหัสด้านบน) ข้อดีอย่างหนึ่งคือการที่คุณจะมีบันทึกของจำนวนบรรทัดในไฟล์ในที่/NR
FNR