अच्छा रास्ता
आम तौर पर आप इसे grep के साथ नहीं कर सकते हैं लेकिन आप अन्य उपकरणों का उपयोग कर सकते हैं। AWK का उल्लेख पहले ही किया जा चुका था लेकिन आप इसका उपयोग भी कर सकते हैं sed:
sed -e '1p' -e '/youpattern/!d'
यह काम किस प्रकार करता है:
सैड उपयोगिता प्रत्येक पंक्ति पर व्यक्तिगत रूप से काम करती है, उनमें से प्रत्येक पर निर्दिष्ट कमांड चल रही है। आपके पास कई -eविकल्प निर्दिष्ट करते हुए, कई कमांड हो सकते हैं । हम प्रत्येक कमांड को एक सीमा पैरामीटर के साथ प्रस्तुत कर सकते हैं जो निर्दिष्ट करता है कि क्या यह कमांड विशिष्ट लाइन पर लागू होना चाहिए या नहीं।
"Ip" एक पहली कमांड है। यह pकमांड का उपयोग करता है जो आम तौर पर सभी लाइनों को प्रिंट करता है । लेकिन हम इसे एक संख्यात्मक मूल्य के साथ प्रस्तुत करते हैं जो उस सीमा को निर्दिष्ट करता है जिसे इसे लागू किया जाना चाहिए। यहां, हम उपयोग करते हैं 1जिसका अर्थ है पहली पंक्ति। यदि आप अधिक लाइनें प्रिंट करना चाहते हैं, तो आप प्रिंट करने के लिए पहली लाइन x,ypकहां उपयोग कर सकते हैं x, प्रिंट करने के yलिए अंतिम लाइन है। उदाहरण के लिए पहले 3 पंक्तियों को प्रिंट करने के लिए, आप उपयोग करेंगे1,3p
अगला कमांड वह है dजो सामान्य रूप से बफर से सभी लाइनों को हटा देता है। इस कमांड से पहले हम yourpatternदो /अक्षरों के बीच में रखते हैं । यह दूसरा तरीका है (पहले यह निर्दिष्ट करना था कि किन पंक्तियों को हमने pकमांड के साथ किया है ) उन पंक्तियों को संबोधित करते हुए जो कमांड को चलाने चाहिए। इसका मतलब है कि कमांड केवल उन लाइनों के लिए काम करेगा जो मैच करते हैं yourpattern। सिवाय, हम !चरित्र से पहले dकमांड का उपयोग करते हैं जो इसके तर्क को प्रभावित करता है। तो अब यह उन सभी लाइनों को हटा देगा जो निर्दिष्ट पैटर्न से मेल नहीं खाती हैं।
अंत में, सीड बफर में छोड़ी गई सभी लाइनों को प्रिंट करेगा। लेकिन हमने उन लाइनों को हटा दिया जो बफर से मेल नहीं खाती हैं, इसलिए केवल मिलान वाली लाइनें मुद्रित की जाएंगी।
योग करने के लिए: हम 1 लाइन प्रिंट करते हैं, फिर हम उन सभी लाइनों को हटा देते हैं जो इनपुट से हमारे पैटर्न से मेल नहीं खाती हैं। लाइनों के बाकी (ताकि केवल लाइनों कि मुद्रित कर रहे हैं करने के आकार से मिलान)।
पहली पंक्ति की समस्या
जैसा कि टिप्पणियों में उल्लेख किया गया है, इस दृष्टिकोण के साथ एक समस्या है। यदि निर्दिष्ट पैटर्न पहली पंक्ति से मेल खाता है, तो इसे दो बार मुद्रित किया जाएगा (एक बार pकमांड द्वारा और एक बार मैच के कारण)। हम इससे दो तरह से बच सकते हैं:
के 1dबाद कमांड जोड़ना 1p। जैसा कि मैंने पहले ही उल्लेख किया है, dकमांड बफर से लाइनों को हटाता है और हम निर्दिष्ट करते हैं कि यह संख्या 1 से है, जिसका अर्थ है कि यह केवल 1 लाइन को हटा देगा। तो आज्ञा होगीsed -e '1p' -e '1d' -e '/youpattern/!d'
1bइसके बजाय, कमांड का उपयोग करना 1p। यह एक चाल है। bकमांड हमें एक लेबल द्वारा निर्दिष्ट अन्य कमांड पर कूदने की अनुमति देता है (इस तरह कुछ कमांड को छोड़ा जा सकता है)। लेकिन अगर यह लेबल निर्दिष्ट नहीं है (जैसा कि हमारे उदाहरण में) यह केवल कमांड के अंत में कूदता है, हमारी लाइन के लिए बाकी कमांड को अनदेखा करता है। तो हमारे मामले में, अंतिम dकमांड बफर से इस लाइन को नहीं हटाएगी।
पूर्ण उदाहरण:
ps aux | sed -e '1b' -e '/syslog/!d'
अर्धविराम का उपयोग करना
कुछ sedकार्यान्वयन कई -eविकल्पों का उपयोग करने के बजाय अलग-अलग कमांड के लिए अर्धविराम का उपयोग करके आपको कुछ टाइपिंग बचा सकते हैं। इसलिए यदि आप पोर्टेबल होने की परवाह नहीं करते हैं तो कमांड होगी ps aux | sed '1b;/syslog/!d'। यह कम से कम GNU sedऔर busyboxकार्यान्वयन में काम करता है ।
पागल तरीका है
हालांकि, यहाँ grep के साथ ऐसा करने के लिए पागल तरीका है। यह निश्चित रूप से इष्टतम नहीं है, मैं इसे केवल सीखने के उद्देश्यों के लिए पोस्ट कर रहा हूं, लेकिन आप इसका उपयोग उदाहरण के लिए कर सकते हैं, यदि आपके पास अपने सिस्टम में कोई अन्य उपकरण नहीं है:
ps aux | grep -n '.*' | grep -e '\(^1:\)\|syslog'
यह काम किस प्रकार करता है
सबसे पहले, हम -nप्रत्येक पंक्ति से पहले लाइन नंबर जोड़ने के लिए विकल्प का उपयोग करते हैं। हम उन सभी लाइनों को सुन्न करना चाहते हैं जिन्हें हम मेल कर रहे हैं .*- कुछ भी, यहां तक कि खाली लाइन भी। जैसा कि टिप्पणियों में सुझाया गया है, हम '^' का भी मिलान कर सकते हैं, परिणाम समान है।
तब हम विस्तारित नियमित अभिव्यक्तियों का उपयोग कर रहे हैं ताकि हम \|विशेष चरित्र का उपयोग कर सकें जो OR के रूप में काम करता है। तो हम मेल खाते हैं यदि रेखा के साथ शुरू होता है 1:(पहली पंक्ति) या इसमें हमारा पैटर्न होता है (इस मामले में इसका syslog)।
लाइन नंबर की समस्या
अब समस्या यह है, हम अपने उत्पादन में यह बदसूरत लाइन नंबर प्राप्त कर रहे हैं। यदि यह एक समस्या है, तो हम उन्हें cutइस तरह से दूर कर सकते हैं :
ps aux | grep -n '.*' | grep -e '\(^1:\)\|syslog' | cut -d ':' -f2-
-dविकल्प सीमांकक निर्दिष्ट करता है, -fउन क्षेत्रों (या स्तंभों) को निर्दिष्ट करता है जिन्हें हम प्रिंट करना चाहते हैं। इसलिए हम प्रत्येक :वर्ण पर प्रत्येक रेखाओं को काटना चाहते हैं और केवल 2nd और उसके बाद के सभी स्तंभों को प्रिंट करना चाहते हैं। यह प्रभावी रूप से पहला कॉलम हटाता है जिससे यह सीमांकित होता है और यह ठीक वैसा ही है जैसा हमें चाहिए।
ackइतना उपयोगी होते हैं, और क्योंperlपहुंचा अतीतsed,awkआदि लोकप्रियता में: यह भागों एक सुसंगत पूरे में योग करने के लिए महत्वपूर्ण है।