मैं बैश स्क्रिप्ट में awk के साथ मल्टी-लाइन रिकॉर्ड कैसे संसाधित कर सकता हूं?


14

example.txt नीचे है

Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911

Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

मैं बैश स्क्रिप्ट का उपयोग कर रहा हूं और कहता हूं कि मैं ऊपर की फ़ाइल से उसके नाम से एक रेस्तरां खोजना चाहता हूं। रेस्तरां के नाम के लिए उपयोगकर्ता इनपुट से पूछें और उसे उस रेस्तरां (5 लाइनों) से संबंधित जानकारी प्रिंट करनी चाहिए।

awk '/McDonalds/> /KFC/' example.txt

मुझे पता है कि ऊपर दी गई कोड की लाइन "मैकडॉनल्ड्स" और "केएफसी" पैटर्न से मेल खाने वाली पूरी लाइन को प्रिंट कर देगी, लेकिन यह सिर्फ टेक्स्ट फाइल से 1 लाइन को प्रिंट करेगा, लेकिन उस रेस्तरां के बारे में बाकी जानकारी नहीं। मैं यह कैसे कह सकता हूं कि रेस्तरां के नाम के उपयोगकर्ता इनपुट से सभी जानकारी (5 नंबर) प्रिंट करें?

जवाबों:


11

जाग के साथ, आप रिकॉर्ड विभाजक को बदल सकते हैं । डिफ़ॉल्ट रूप से यह एक नई पंक्ति है, इसलिए फ़ाइल की प्रत्येक पंक्ति एक रिकॉर्ड है। यदि आप RSवैरिएबल को खाली स्ट्रिंग पर सेट करते हैं , तो awk रिक्त लाइनों द्वारा अलग किए जाने के रिकॉर्ड पर विचार करेगा:

awk -v name="KFC" -v RS="" '$0 ~ "Restaurant: " name' example.txt

मैं आपके सवाल को नहीं समझता। यह काफी अस्पष्ट है। क्या यह असाइनमेंट या उपयोग है जो आपको नहीं मिलता है?
ग्लेन जैकमैन

3

का उपयोग कर sed:

$ sed -n '/KFC/,/^$/p' file
Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

$ sed -n '/McDo/,/^$/p' file
Restaurant: McDonalds
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

व्याख्या

यह मूल sedकार्य है, आप SED के लिए USEFUL ONE-LINE SCRIPTS का उल्लेख कर सकते हैं

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive

स्पष्टीकरण जोड़ें।
बीएमडब्लू

लेकिन सुझाए गए संपादन को अस्वीकार क्यों किया गया? मैंने जवाब नहीं बदला। मैंने सिर्फ स्वरूपण में सुधार किया है।
डेज़ी

2
$ awk '$2=="KFC" {print; for(i=1; i<=4; i++) { getline; print}}' example.txt

Restaurant: KFC
City: NYC
State: NY
Address: 123 Madison Square
Phone: 911

उपरोक्त कमांड चालू लाइन के साथ लगातार 4 लाइनों को मिलेगा और प्रिंट करेगा क्योंकि इसे लूप के लिए फीड किया गया था। सर्च पैटर्न $2=="KFC"कई लाइनों से एक विशेष लाइन प्राप्त करने में मदद करेगा।


0

एक अन्य संभावित समाधान:

awk 'BEGIN{FS="\n";RS="\n\n"}{if($1=="KFC")print $0}' example.txt

{if($1=="KFC")print $0}बस के लिए सघन किया जा सकता है $1 == "KFC", के बाद से एक सच्चे हालत के लिए डिफ़ॉल्ट कार्रवाई रिकॉर्ड मुद्रित करने के लिए है।
मुरु

0

यह उस पंक्ति से प्रिंट करना पर्याप्त है जिसमें आप अपना नाम चाहते हैं, अंतिम पंक्ति में शब्द Phone(निश्चित रूप से यह मानते हुए कि सभी प्रविष्टियां एक ही पैटर्न का पालन करती हैं और हमेशा Phoneसमाप्ति रिकॉर्ड के रूप में होंगी )

$> awk '/5 guys/,/Phone/' restaurants.txt                                     
Restaurant: 5 guys
City: Atlanta
State: Georgia
Address: 123 Peachtree Rd
Phone: 911
$> awk '/McDonalds/,/Phone/' restaurants.txt                                  
Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

यदि हम इसे थोड़ा जटिल करना चाहते हैं, तो हम मैच के बाद ठीक 5 लाइनें प्रिंट कर सकते हैं, जैसे:

awk '/McDonalds/{stop=NR+5}; NR<=stop ' restaurants.txt                    

Restaurant: McDonalds 
City: Miami
State: Florida
Address: 123 Biscayne Blvd
Phone: 911

stopचर सेट नहीं किया जाएगा, तो NR<=stopकुछ भी प्रिंट नहीं होगा, जब तक /McDonalds/{stop=NR+5;}हिस्सा वास्तव में चर सेट, और कहा कि केवल होगा जब हम मैच पाते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.