आप एक ही चरित्र (जैसे पारंपरिक कार्यान्वयन करते हैं) या एक नियमित अभिव्यक्ति (जैसे या करो) के रूप में awk
व्यवहार करते हैं, इस पर निर्भर करते हुए आप अलग-अलग दृष्टिकोण अपना सकते हैं । खाली फ़ाइलों को भी मुश्किल माना जाता है ताकि उन्हें छोड़ दिया जा सके।RS
awk
gawk
mawk
awk
gawk
, mawk
या अन्य awk
कार्यान्वयन जहां RS
एक regexp हो सकता है।
उन कार्यान्वयनों में (के लिए mawk
, सावधान रहें कि कुछ OS जैसे डेबियन जहाज को पुराने संस्करण के बजाय @ThomasDickey द्वारा बनाए गए आधुनिक संस्करण में रखा गया है ), यदि RS
एक एकल वर्ण होता है, तो रिकॉर्ड विभाजक वह वर्ण होता है, या रिक्त awk
होने पर पैराग्राफ मोड में प्रवेश करता है। RS
या RS
अन्यथा एक नियमित अभिव्यक्ति के रूप में व्यवहार करता है ।
वहाँ समाधान एक नियमित अभिव्यक्ति का उपयोग करना है जो संभवतः मेल नहीं खा सकता है। कुछ की तरह मन के लिए आते हैं x^
या $x
( x
शुरू होने से पहले, या अंत के बाद)। हालांकि कुछ (विशेषकर के साथ gawk
) दूसरों की तुलना में अधिक महंगे हैं। अब तक, मैंने पाया है कि ^$
सबसे कुशल एक है। यह केवल एक खाली इनपुट पर मेल कर सकता है, लेकिन तब मैच के लिए कुछ भी नहीं होगा।
तो हम कर सकते हैं:
awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
एक चेतावनी यह है कि यह खाली फाइलों को छोड़ देती है (इसके विपरीत perl -0777 -n
)। इसके बजाय awk
एक ENDFILE
बयान में कोड डालकर जीएनयू के साथ संबोधित किया जा सकता है । लेकिन हमें $0
एक BEGINFILE स्टेटमेंट में रीसेट करने की भी आवश्यकता है क्योंकि यह अन्यथा खाली फाइल को संसाधित करने के बाद रीसेट नहीं किया जाएगा:
gawk -v RS='^$' '
BEGINFILE{$0 = ""}
ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...
पारंपरिक awk
कार्यान्वयन, POSIXawk
उन में, RS
सिर्फ एक चरित्र है, उनके पास BEGINFILE
/ नहीं है ENDFILE
, उनके पास RT
चर नहीं है , वे आम तौर पर एनयूएल चरित्र को संसाधित नहीं कर सकते हैं।
आपको लगता है कि RS='\0'
तब काम कर सकता था, क्योंकि वैसे भी वे एनयूएल बाइट वाले इनपुट को संसाधित नहीं कर सकते हैं, लेकिन नहीं, RS='\0'
पारंपरिक कार्यान्वयन में ऐसा माना जाता है RS=
, जो पैराग्राफ मोड है।
एक समाधान एक चरित्र का उपयोग करने के लिए हो सकता है जो इनपुट में पाए जाने की संभावना नहीं है \1
। मल्टीबाइट कैरेक्टर लोकेशन्स में, आप इसे बाइट-सीक्वेंस भी बना सकते हैं, $'\U10FFFE'
जो यूटीएफ -8 लोकेशन्स की तरह कैरेक्टर नहीं बनाते या असाइन नहीं किए जाते हैं । हालांकि वास्तव में मूर्ख नहीं है और आपको खाली फाइलों के साथ भी समस्या है।
एक अन्य समाधान पूरे इनपुट को एक चर में संग्रहीत करना और अंत में कथन में इसे संसाधित करना हो सकता है। इसका मतलब है कि आप एक समय में केवल एक ही फ़ाइल को संसाधित कर सकते हैं:
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
।