Bạn có thể thực hiện các cách tiếp cận khác nhau tùy thuộc vào việc awkxử lý RSnhư một ký tự đơn lẻ (như cách awktriển khai truyền thống ) hoặc như một biểu thức thông thường (thích gawkhoặc mawklàm). Các tập tin trống cũng rất khó để được coi là awkcó xu hướng bỏ qua chúng.
gawk, mawkHoặc khác awktriển khai ở đâu RScó thể là một biểu thức chính quy.
Trong các triển khai đó (đối với mawk, hãy cẩn thận rằng một số HĐH như Debian gửi phiên bản rất cũ thay vì phiên bản hiện đại được duy trì bởi @ThomasDickey ), nếu RSchứa một ký tự, dấu tách bản ghi là ký tự đó hoặc awkvào chế độ đoạn khi RStrống, hoặc coi RSnhư một biểu thức thông thường khác.
Giải pháp là sử dụng một biểu thức chính quy không thể phù hợp. Một số đến với tâm trí như x^hoặc $x( xtrước khi bắt đầu, hoặc sau khi kết thúc). Tuy nhiên, một số (đặc biệt với gawk) đắt hơn những cái khác. Cho đến nay, tôi đã thấy rằng đó ^$là một cách hiệu quả nhất. Nó chỉ có thể khớp với đầu vào trống, nhưng sau đó sẽ không có gì phù hợp.
Vì vậy, chúng ta có thể làm:
awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
Một điều lưu ý là nó bỏ qua các tập tin trống (trái với perl -0777 -n). Điều đó có thể được giải quyết với GNU awkbằng cách đặt mã trong một ENDFILEcâu lệnh thay thế. Nhưng chúng ta cũng cần đặt lại $0trong câu lệnh BEGINFILE vì nếu không nó sẽ không được đặt lại sau khi xử lý tệp trống:
gawk -v RS='^$' '
BEGINFILE{$0 = ""}
ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
awktriển khai truyền thống , POSIXawk
Trong đó, RSchỉ là một ký tự, họ không có BEGINFILE/ ENDFILE, họ không có RTbiến, họ thường không thể xử lý ký tự NUL.
Bạn sẽ nghĩ rằng việc sử dụng RS='\0'có thể hoạt động sau đó vì dù sao họ không thể xử lý đầu vào có chứa byte NUL, nhưng không, RS='\0'trong các triển khai truyền thống được coi RS=là chế độ đoạn văn.
Một giải pháp có thể là sử dụng một ký tự không chắc chắn được tìm thấy trong đầu vào như thế nào \1. Trong các địa điểm ký tự đa nhân, bạn thậm chí có thể tạo ra các chuỗi byte rất khó xảy ra khi chúng tạo thành các ký tự không được gán hoặc không phải ký tự như $'\U10FFFE'trong các địa phương UTF-8. Mặc dù không thực sự hoàn hảo và bạn cũng gặp vấn đề với các tập tin trống.
Một giải pháp khác có thể là lưu trữ toàn bộ đầu vào trong một biến và xử lý nó trong câu lệnh END ở cuối. Điều đó có nghĩa là bạn chỉ có thể xử lý một tệp tại một thời điểm:
awk '{content = content $0 RS}
END{$0 = content
printf "%s: <%s>\n", FILENAME, $0
}' file
Đó là tương đương với sed:
sed '
:1
$!{
N;b1
}
...' file1
Một vấn đề khác với cách tiếp cận đó là nếu tệp không kết thúc bằng ký tự dòng mới (và không trống), $0thì cuối cùng vẫn được thêm vào một cách tùy tiện (với gawk, bạn sẽ xử lý xung quanh bằng cách sử dụng RTthay vì RStrong mã ở trên). Một lợi thế là bạn có bản ghi số lượng dòng trong tệp trong NR/ FNR.