2013-08-23 3 views
16

समझाएं आज मैं पैटर्न के बाद अगली दो पंक्तियों को मुद्रित करने के लिए ऑनलाइन कमांड खोज रहा था और मैं एक अजीब कमांड में आया जो मुझे समझ में नहीं आया।awk कमांड

$ /usr/xpg4/bin/awk '_&&_--;/PATTERN/{_=2}' input 

क्या कोई इसे समझा सकता है?

उत्तर

2

आश्चर्यजनक रूप से अस्पष्ट। समय की अनुमति देता है जब अद्यतन करेगा।

_ एक चर नाम के रूप में उपयोग किया जा रहा है। && एक तार्किक ऑपरेटर है जिसमें 2 सच्चे कार्य एक साथ चलते हैं। एक बार _ का मान शून्य हो गया है, & & का दूसरा भाग गलत है और कोई आउटपुट उत्पन्न नहीं होता है।

print -- " 
xxxxx 
yyyy 
PATTERN 
zzz 
aa 
bbb 
ccc 
ddd" | awk '_&&_--;/PATTERN/{_=2}' 

उत्पादन

zzz 
aa 

डिबग संस्करण

print -- " 
xxxxx 
yyyy 
PATTERN 
zzz 
aa 
bbb 
ccc 
ddd" | awk '_&&_--;{print "_="_;print _&&_};/PATTERN/{_=2;print "_="_ }' 

उत्पादन

_= 
0 
_= 
0 
_= 
0 
_= 
0 
_=2 
zzz 
_=1 
1 
aa 
_=0 
0 
_=0 
0 
_=0 
0 
_=0 
0 
7

बस दिए गए लाइन समेत एक नियमित नियमित अभिव्यक्ति अभिव्यक्ति मिलान के बाद कमांड को कई पंक्तियों को मुद्रित करें।

ब्लॉक {_=2} में पंक्तियों की संख्या निर्दिष्ट है और PATTERN से मेल खाने वाली चर _ परिवर्तनीय है। मिलान रेखा के बाद पढ़ने वाली प्रत्येक पंक्ति _ को कम करने के कारण बनती है। आप _&&_-- पढ़ सकते हैं जैसे कि _ शून्य से अधिक है तो इससे कम से कम एक, यह _ शून्य तक एक मैच के बाद प्रत्येक पंक्ति के लिए होता है। जब आप n जैसे अधिक समझदार नाम के साथ परिवर्तनीय _ को प्रतिस्थापित करते हैं तो यह काफी आसान है।

एक साधारण डेमो यह स्पष्ट करना चाहिए (2 लाइनों कि foo मिलान किसी भी लाइन का पालन करें मुद्रित):

$ cat file 
foo 
1 
2 
3 
foo 
a 
b 
c 

$ awk 'n && n--;/foo/{n=2}' file 
1 
2 
a 
b 

तो n केवल यह सच है जब यह तो यह foo के साथ एक पंक्ति मिलान के बाद 2 करने के लिए सेट हो जाता है n में कमी और वर्तमान पंक्ति प्रिंट करता है। कारण awk शॉर्ट सर्किट मूल्यांकन n होने के लिए केवल घटती है जब n यह सच है (एन> 0) तो n के लिए इस मामले में केवल संभावित मान 2,1 या 0.

Awk निम्नलिखित संरचना है कर रहे हैं condition{block} और जब एक शर्त का मूल्यांकन किया जाता है तो सही रिकॉर्ड के लिए ब्लॉक को निष्पादित किया जाता है। यदि आप ब्लॉक awk प्रदान नहीं करते हैं तो डिफ़ॉल्ट ब्लॉक {print $0} का उपयोग करता है, इसलिए n && n--; एक ब्लॉक के बिना एक शर्त है जो नियमित अभिव्यक्ति मिलान के बाद n लाइनों के लिए केवल सही पर मूल्यांकन करती है। /foo/ शर्तों के लिए सेमी-कोलन बस n&&n-- की स्थिति को सीमित करता है, यह स्पष्ट करता है कि स्थिति में कोई ब्लॉक नहीं है।

मैच सहित मैच आप क्या करेंगे निम्नांकित दो पंक्तियों को प्रिंट करने के लिए:

$ awk '/foo/{n=3} n && n--' file 
foo 
1 
2 
foo 
a 
b 

अतिरिक्त अतिरिक्त: तथ्य यह है कि /usr/xpg4/bin/awk का पूरा पथ प्रयोग किया जाता है मुझसे कहता है इस कोड को एक सोलारिस के लिए है /usr/bin/awk के रूप में मशीन पूरी तरह टूटा हुआ है और हर कीमत से बचा जाना चाहिए।

+2

बहुत अच्छी स्पष्टीकरण – CBR

11

_ यहां एक चर नाम के रूप में उपयोग किया जा रहा है (मान्य लेकिन स्पष्ट रूप से भ्रमित)। यदि आप इसे फिर से लिखते हैं:

awk 'x && x--; /PATTERN/ { x=2 }' input 

तो यह पार्स करना थोड़ा आसान है। जब भी /PATTERN/ मिलान किया जाता है, तो चर 2 पर सेट हो जाता है (और वह पंक्ति आउटपुट नहीं है) - यह दूसरा आधा है। पहला भाग आग लगता है जब x शून्य नहीं है, और x में कमी के साथ-साथ वर्तमान लाइन को प्रिंट करना (डिफ़ॉल्ट क्रिया, क्योंकि उस खंड में कोई क्रिया निर्दिष्ट नहीं होती है)।

अंतिम परिणाम पैटर्न के किसी भी मैच के तुरंत बाद दो पंक्तियों को मुद्रित करना है, जब तक कि इनमें से कोई भी पंक्ति पैटर्न से मेल नहीं खाती। यदि conditon सच कार्रवाई (रों) है निष्पादित किया जाएगा

condition action; NEXT_EXPRESSION 

:

2

स्पष्टीकरण

awk भाव निम्न प्रपत्र की है। आगे ध्यान दें, यदि स्थिति सत्य है लेकिन कार्रवाई को छोड़ दिया गया है awkprint (डिफ़ॉल्ट कार्रवाई) निष्पादित करेगा।

_&&_--   ; 
/PATTERN/{_=2} 

दोनों एक ; से अलग होते हैं:

अपने कोड के दो भाव है कि इनपुट के हर लाइन पर निष्पादित हो जाएगा। जैसा कि मैंने कहा था कि डिफ़ॉल्ट कार्रवाई print अगर कार्रवाई यह है छोड़ दिया जाता है क्या होगा एक ही रूप में:

_&&_-- {print}; 
/PATTERN/ {_=2} 

अपने उदाहरण में _ एक चर नाम है, जो इनपुट की पहली पंक्ति पर 0 से प्रारंभ हो जाता है, पहले उपयोग से पहले - स्वचालित रूप से अजीब द्वारा।

पहली स्थिति (0) && (0) होगी .. स्थिति में झूठ होने का क्या परिणाम है, 0 && 0false का मूल्यांकन करता है और अजीब प्रिंट नहीं करेगा।

तो पैटर्न पाया जाता है, _2 जो पहली शर्त को अगली पंक्ति अगली पंक्ति (2) && (2) और (1) && (1) जा रहा है बनाता है _ के रूप में है कि रेखा के बाद के बाद हालत मूल्यांकन किया जा रहा है कम कर रहा है करने के लिए स्थापित किया जाएगा। दोनों true पर मूल्यांकन कर रहे हैं और उन पंक्तियों को अजीब प्रिंट करेंगे।

हालांकि, अच्छा पहेली;)

+0

थोड़ा गलती, पोस्ट-कमीशन में उच्च आदेश या प्राथमिकता है जो तार्किक और स्पष्ट रूप से '(0) && (0 -)' '(0 && 0) -' के रूप में मूल्यांकन करता है। –

+0

जानना अच्छा लगा .. मुझे इस तरह से पोस्ट को बढ़ाने दें। – hek2mgl

+0

@sudo_O 'awk '_ &&_--; 1 {printf"% i \ n ", _};/पैटर्न/{_ = 2}' input.txt' मैं ऊपर की रेखा के आउटपुट को समझ नहीं पा रहा हूं। यदि पहले घटता है (अजीब दस्तावेज़ों के अनुरूप क्या है, तो आप सही हैं), फिर पैटर्न के मिलान के बाद पहले टेस्ट में 0 और ''का सही पक्ष 1 और 1 होना चाहिए। तो मैं उम्मीद करता हूं कि सिर्फ एक पंक्ति मुद्रित की जाएगी .. मुझे यहाँ क्या याद आ रही है? – hek2mgl

36

जवाब यह है कि यहां दोहराया गया था के लिए https://stackoverflow.com/a/17914105/1745001 देखें।

+2

क्या संग्रह है! +1 – iruvar

+2

वाह! awk कमांड वास्तव में एक सोने की खान है। – CBR

+2

+1 अच्छी तरह से योग्य बक्षीस! –