मैच के लिए सभी फ़ाइल दिखाएँ


71

grep --before-context 5 मैच से पहले 5 लाइनें दिखाता है।

मैं मैच से पहले सबकुछ दिखाना चाहता हूं। काम
करना grep --before-context 99999999होगा लेकिन यह बहुत ... पेशेवर नहीं है।

मैच तक सभी फ़ाइल कैसे दिखाएं?

जवाबों:


95

इसके लिए सेड बेहतर है।

बस करो:

sed '/PATTERN/q' FILE

यह इस तरह काम करता है:

प्रत्येक पंक्ति के लिए, हम देखते हैं कि क्या यह मेल खाता है /PATTERN:

  • यदि हां, तो हम इसे प्रिंट करते हैं और छोड़ देते हैं
  • अन्यथा, हम इसे प्रिंट करते हैं

यह सबसे कुशल समाधान है, क्योंकि जैसे ही यह देखता है PATTERN, यह क्विट करता है। बिना q, sed फ़ाइल के शेष भाग को पढ़ना जारी रखेगा और इसके साथ कुछ भी नहीं करेगा। बड़ी फ़ाइलों के लिए यह एक अंतर बना सकता है।

इस ट्रिक का इस्तेमाल अनुकरण करने के लिए भी किया जा सकता है head:

sed 10q FILE

बस कोशिश की, यह फ़ाइल की पहली पंक्ति का आउटपुट देता है ... भले ही मैच लाइन 38 पर हो।
निकोलस राउल

मेरे लिए ठीक काम करता है। क्या आप वास्तविक इनपुट और आउटपुट का उदाहरण दे सकते हैं? और आप जो कमांड चला रहे हैं, वह है।
मिकेल

इससे पहले कि आप इसे संपादित करते, मैंने आपकी आज्ञा की कोशिश की थी, यह था: sed '/ PATTERN / p; q' FILE
निकोलस राउल

7
यदि मुझे पैटर्न मैच के साथ लाइन प्रिंट नहीं करना है तो मुझे क्या करना चाहिए?
tommy.carstensen

4
@ tommy.carstensen: sed '/PATTERN/Q' FILEमिलान की गई रेखा को छोड़ देगा। Qयह GNU एक्सटेंशन है, इसलिए यह किसी भी सेड के साथ काम नहीं करेगा।
एलेक्स ओ

37

sed grep की अधिकांश कार्यक्षमता को प्रतिस्थापित कर सकता है।

sed -n '1,/<pattern>/ p' <file>

इसका मतलब है कि पैटर्न से मिलान होने तक पहली पंक्ति से प्रिंट।

रेंज के कुछ उदाहरण

sed -n '/<pattern>/,$ p' <file> # from pattern to end of file
sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2

3
यह कमांड अच्छा है, लेकिन आप बेहतर कर सकते हैं। इस तरह से यह पूरी फाइल को पढ़ता है, लेकिन जैसे ही इसने मैच पाया है इसे छोड़ना संभव है।
मिकेल

3
यदि मुझे पैटर्न मैच के साथ लाइन प्रिंट नहीं करना है तो मुझे क्या करना चाहिए?
tommy.carstensen

34

मैच के लिए और सहित प्रिंट करें:

awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename

मैच सहित BUT तक प्रिंट न करें:

awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename

11
Qअच्छा है, लेकिन ग्नू विशिष्ट afaik, sed -n '/pattern/!p;//q'अधिक पोर्टेबल होगा।
दान_क्रांति

@don_crissti: आपको इसका उत्तर देना चाहिए, मुझे लगता है कि यह एक अच्छा है (: मैं थोड़ा उत्सुक हूं कि यह कैसे काम करता है, हालांकि, मेरा मानना !है कि यह मेल नहीं खाता pलाइनों पर लागू होता है , लेकिन फिर मुझे भ्रमित करता है ...pattern//q
jwd

2
@don_crissti: आह, मुझे मिल गया - //इसका मतलब है "पिछले नियमित अभिव्यक्ति" (मुझे लगा कि इसका मतलब "खाली स्ट्रिंग से मेल खाता है")। मुझे लगता है कि एक ही समाधान का एक छोटा संस्करण है sed -n '/pattern/q;p:?
jwd

@jwd - वास्तव में, यह छोटा है। 👍
don_crissti

1

निम्नलिखित शुद्ध GNU grepविधियाँ कुशल नहीं हैं।

तीन बार उपयोग करके फ़ाइल बार में स्ट्रिंग " फू " के पहले उदाहरण तक सब कुछ खोजें :grep

grep -m 1 -B $(grep -n -m 1 foo bar | grep -o '^[0-9]*') foo bar

" फू " के अंतिम उदाहरण तक मिलान :

grep -oPz "(?s)[^\n]*${s}.*?\n.*?foo.*?\n" bar

नोट: अंतिम विवरण grepमें पाया जा सकता है: बहु-पंक्ति खोज के लिए Regex (grep) की आवश्यकता है


grepजब कोई बस एकल sedआह्वान चलाने की बात करेगा तो कोई 7 s (+ pcre) का उपयोग क्यों करना चाहेगा : sed 'x;/./G;//!x;/foo/p;//s/.*//;x;d'??
डॉन_क्रांति

@don_crissti, आपका sedकोड अपने स्वयं के जवाब के लायक लगता है, या दूसरों में से एक में जोड़ा जा सकता है। पुनः 7 greps: क्योंकि कोई grepउत्तर नहीं था ... (साथ ही, उत्तर यह दिखाने में मदद करता है कि क्यों नहीं।)
agc

यह मेरा कोड नहीं है, बस उस पर क्लिक करें ... यहां तक ​​कि अगर मेरा कोड था, तो यह यहां क्यू का जवाब नहीं देता है इसलिए मैं इसे उत्तर के रूप में पोस्ट नहीं करूंगा।
don_crissti

1

ऊपर मिकेल के जवाब में जोड़ना ...


सभी पंक्तियों को प्रिंट करने के लिए, लेकिन शामिल नहीं है , जिसमें पहली पंक्ति FILEशामिल है PATTERN, कोशिश करें:

  • sed '/.*PATTERN.*/{s///;q;}' FILE

यह पैटर्न वाली पूरी लाइन से मेल खाता है, इसे एक खाली लाइन से बदल देता है, फिर बाकी फाइल को प्रोसेस किए बिना क्विट करता है।


परिशिष्ट भाग:

सबसे आसान / स्पष्ट तरीका है कि मैं अंत में एक और नई लाइन को प्रिंट करने से रोकने के बारे में सोच सकता हूं (दूसरे टूल को शामिल किए बिना), फिर से sed चलाना और नई अंतिम लाइन को हटाना था:

sed '/.*PATTERN.*/{s///;q;}' FILE | sed '$d'

... और चूँकि हम अब उस लाइन को वैसे भी हटा रहे हैं, हमारा पिछला काम बेमानी है और हम इसे सरल बना सकते हैं:

sed '/PATTERN/q' FILE | sed '$d'

ग्लेन का जवाब - और मेरी टिप्पणी वहाँ - एक एकल sedआह्वान के साथ कैसे करें यह दिखाएं ।
दान_क्रांति

(इसके लिए धन्यवाद - मैंने एगसी के उत्तर पर आपकी टिप्पणी को देखा था, लेकिन या तो दूसरे को याद किया या सिर्फ इसलिए इसे छोड़ दिया क्योंकि मेरा मस्तिष्क दोहरे नकारात्मक को नापसंद करता है।) चूंकि मैं एक tcshऔर एक bashअन्य दोनों में इसका उपयोग कर रहा था , इसलिए मुझे यह सुनिश्चित करने की आवश्यकता थी कि मैं सुनिश्चित करूं। अपेक्षाकृत संक्षिप्त एक-लाइन समाधान था जो मानक और GNU sed(पोर्टेबिलिटी दोनों ) में काम करता था; सभी आवश्यकताएं जो आपके योगदान को बहुत अच्छी तरह से पूरा कर सकती हैं। जैसा कि कोई है जो शायद sed ही कभी उपयोग करता है , मेरी सबसे महत्वपूर्ण आवश्यकता कुछ ऐसी चीज थी जिसे मैं जल्दी से समझ सकता हूं जब मैं इसे आसानी से संपादित करना चाहता हूं या इसे अब तक पुनः उपयोग कर सकता हूं।
जिम ग्रिशम

1

उन लोगों के लिए जो दिन-प्रतिदिन के काम में केवल बुनियादी उपकरणों को याद रखना चाहते हैं, और कम सुरुचिपूर्ण और कम कुशल समाधानों को स्वीकार करने को तैयार हैं:

head -n $(grep -n pattern filename | cut -d: -f1) filename

यदि यह कमांड एक स्क्रिप्ट के लिए है, तो मैं और अधिक सुरुचिपूर्ण (और संभवतः कुशल) समाधानों की तलाश करूंगा। अगर यह एक समय की कमांड है या स्क्रिप्ट को फेंक दें तो मुझे कोई फर्क नहीं पड़ता।


1
अच्छा विचार है, लेकिन तीन आज्ञाएँ जब कोई करेगा।
मिकेल

1
मूल बातें जानना वास्तव में बहुत अच्छा है। नौकरी के लिए सही उपकरण जानना बेहतर है, हालांकि।
सोलमरेज १४'११

यदि यह कमांड एक स्क्रिप्ट के लिए है, तो मैं और अधिक सुरुचिपूर्ण (और संभवतः कुशल) समाधानों की तलाश करूंगा। यदि यह एक समय का आदेश है (या स्क्रिप्ट को फेंक दें), तो मुझे कोई फर्क नहीं पड़ता।
घावना

0

आप निम्न में से किसी एक का भी उपयोग कर सकते हैं

tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac 

या

tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac

या

tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac

पहला विकल्प बहुत कुछ वैसा ही है जैसा कि ओपी ने सुझाव दिया था कि यह सुनिश्चित करता है कि फाइल में लाइनों को गिनकर टीआई संदर्भ से पहले पर्याप्त लाइनें दिखा सके

दूसरा विकल्प पहले मैच की लाइन नंबर को खोजता है (आप इसे बदल सकते हैं और साथ ही आंतरिक 'हेड' को बदल सकते हैं) और इस नंबर पर उपयोग की तुलना में

अंतिम विकल्प मैच के साथ सभी नई लाइनों को बदल देता है और दो आसन्न मैचों को एक नई लाइन के साथ बदल देता है। इसका आउटपुट दो मैचों के बीच पाठ के प्रत्येक ब्लॉक के लिए एक पंक्ति है। इसके बाद पहली पंक्ति चुनने के लिए यह 'हेड' का उपयोग करता है (पहले मैच तक टेक्स्ट के ब्लॉक को लहराता है) मैच करता है और प्रत्येक मैच को एक नई लाइन पर बदल देता है। यह विकल्प केवल तभी काम करता है जब फ़ाइल निम्न प्रारूप में हो

pattern
texttexttext
texttexttext texttexttext
texttexttexttexttexttexttexttexttext
pattern
texttexttext
pattern 
texttexttext
texttexttexttexttexttexttexttexttext

इत्यादि


2
यह समझाने पर विचार करें कि ये कैसे काम करते हैं, विशेष रूप से इसलिए कि sedतल पर यह आदेश एक प्रकार का उल्लास है।
स्ट्रगलर

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