grep --before-context 5 मैच से पहले 5 लाइनें दिखाता है।
मैं मैच से पहले सबकुछ दिखाना चाहता हूं। काम
करना grep --before-context 99999999होगा लेकिन यह बहुत ... पेशेवर नहीं है।
मैच तक सभी फ़ाइल कैसे दिखाएं?
grep --before-context 5 मैच से पहले 5 लाइनें दिखाता है।
मैं मैच से पहले सबकुछ दिखाना चाहता हूं। काम
करना grep --before-context 99999999होगा लेकिन यह बहुत ... पेशेवर नहीं है।
मैच तक सभी फ़ाइल कैसे दिखाएं?
जवाबों:
इसके लिए सेड बेहतर है।
बस करो:
sed '/PATTERN/q' FILE
यह इस तरह काम करता है:
प्रत्येक पंक्ति के लिए, हम देखते हैं कि क्या यह मेल खाता है /PATTERN:
यह सबसे कुशल समाधान है, क्योंकि जैसे ही यह देखता है PATTERN, यह क्विट करता है। बिना q, sed फ़ाइल के शेष भाग को पढ़ना जारी रखेगा और इसके साथ कुछ भी नहीं करेगा। बड़ी फ़ाइलों के लिए यह एक अंतर बना सकता है।
इस ट्रिक का इस्तेमाल अनुकरण करने के लिए भी किया जा सकता है head:
sed 10q FILE
sed '/PATTERN/Q' FILEमिलान की गई रेखा को छोड़ देगा। Qयह GNU एक्सटेंशन है, इसलिए यह किसी भी सेड के साथ काम नहीं करेगा।
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
मैच के लिए और सहित प्रिंट करें:
awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename
मैच सहित BUT तक प्रिंट न करें:
awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename
Qअच्छा है, लेकिन ग्नू विशिष्ट afaik, sed -n '/pattern/!p;//q'अधिक पोर्टेबल होगा।
!है कि यह मेल नहीं खाता pलाइनों पर लागू होता है , लेकिन फिर मुझे भ्रमित करता है ...pattern//q
//इसका मतलब है "पिछले नियमित अभिव्यक्ति" (मुझे लगा कि इसका मतलब "खाली स्ट्रिंग से मेल खाता है")। मुझे लगता है कि एक ही समाधान का एक छोटा संस्करण है sed -n '/pattern/q;p:?
निम्नलिखित शुद्ध 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'??
sedकोड अपने स्वयं के जवाब के लायक लगता है, या दूसरों में से एक में जोड़ा जा सकता है। पुनः 7 greps: क्योंकि कोई grepउत्तर नहीं था ... (साथ ही, उत्तर यह दिखाने में मदद करता है कि क्यों नहीं।)
ऊपर मिकेल के जवाब में जोड़ना ...
सभी पंक्तियों को प्रिंट करने के लिए, लेकिन शामिल नहीं है , जिसमें पहली पंक्ति 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 ही कभी उपयोग करता है , मेरी सबसे महत्वपूर्ण आवश्यकता कुछ ऐसी चीज थी जिसे मैं जल्दी से समझ सकता हूं जब मैं इसे आसानी से संपादित करना चाहता हूं या इसे अब तक पुनः उपयोग कर सकता हूं।
उन लोगों के लिए जो दिन-प्रतिदिन के काम में केवल बुनियादी उपकरणों को याद रखना चाहते हैं, और कम सुरुचिपूर्ण और कम कुशल समाधानों को स्वीकार करने को तैयार हैं:
head -n $(grep -n pattern filename | cut -d: -f1) filename
यदि यह कमांड एक स्क्रिप्ट के लिए है, तो मैं और अधिक सुरुचिपूर्ण (और संभवतः कुशल) समाधानों की तलाश करूंगा। अगर यह एक समय की कमांड है या स्क्रिप्ट को फेंक दें तो मुझे कोई फर्क नहीं पड़ता।
आप निम्न में से किसी एक का भी उपयोग कर सकते हैं
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
इत्यादि
sedतल पर यह आदेश एक प्रकार का उल्लास है।