फ़ाइल के साथ एक पंक्ति का एक भाग sed से निकालें


18

मैं एक फाइल से एक लाइन का एक हिस्सा पढ़ना चाहता हूं। उदाहरण के लिए:

POP3_SERVER_NAME = स्थानीय होस्ट

मैं केवल localhostsed का उपयोग करके वापस लौटना चाहता हूं ।

यह पाठ तीसरी पंक्ति पर है। मैं लाइन निकालने के लिए ऐसा करता हूं:

sed -n '3p' installation.sh

मैं केवल localhostभाग कैसे निकालूं ?

जवाबों:


26

awk यहाँ एक बेहतर उपकरण हो सकता है।

$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost

उन पंक्तियों की खोज करें जिनमें "POP3_SERVER_NAME" शामिल है; अंतिम फ़ील्ड प्रिंट करें। यह हमेशा POP3_SERVER_NAME पर पंक्ति 3 पर निर्भर नहीं करता है, जो कि शायद एक अच्छी बात है।

$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost

आपके आवेदन के आधार पर, आपको नियमित अभिव्यक्ति को अधिक कठोर बनाने की आवश्यकता हो सकती है। उदाहरण के लिए, आप केवल उस पंक्ति से मेल खाना चाहते हैं जो POP3_SERVER_NAME से शुरू होती है

$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost

सेड का उपयोग करना थोड़ा कम सहज है। (धन्यवाद, मैं विडंबना से अवगत हूं।) उस पंक्ति को संबोधित करें जिसमें POP3_SERVER_NAME कहीं भी हो। लाइन की शुरुआत से "=" के बाद वैकल्पिक स्थान तक सभी पाठ के लिए एक खाली स्ट्रिंग को प्रतिस्थापित करें। फिर प्रिंट करें।

sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat

2
awkआदेश अच्छा है - लेकिन आप के साथ स्पेस मिल गया है केवल यदि =। यह काम नहीं करेगा POP3_SERVER_NAME=localhost
मार्सेल ने 11

2
@ मार्सेल, आप awkरिक्त स्थान का उपयोग करने वाले सीमांकक को बदलकर कुछ और का उपयोग कर सकते हैं -F। उदाहरण के लिए: आपके द्वारा उल्लिखित मामले में परिसीमनक के रूप में -F "="उपयोग करेगा =
मैट्रप

7

बदलें pएक प्रतिस्थापन है कि रेखा के अवांछित भाग को हटा द्वारा आदेश।

sed -n '3 s/^[^=]*= *//p' installation.sh

आप स्थिति के बजाय कीवर्ड द्वारा लाइन का मिलान करना चाह सकते हैं।

sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh

6

ऐसा लगता है कि आपको एक कॉन्फ़िग फ़ाइल मिल गई है। आप क्या कर सकते हैं जैसा कि एडम सिएमोन / स्लम सुझाते हैं:

sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename

जहां [^=]शामिल नहीं सब '=' अक्षर, +एक या चरित्र का एक ही प्रकार के और अधिक, यह एक वास्तविक के बाद कहते हैं =, \sकोई श्वेत रिक्ति (टैब को शामिल करते \tहैं और नई लाइनों \n, \r\n, और सादे रिक्त स्थान ', जबकि *साधन शून्य या एक ही प्रकार के और अधिक , कोष्ठक में मिलान किए गए वर्ण अनुक्रमों को \ 1, \ 2, ..., \ n प्रतिस्थापन प्लेसहोल्डर्स में रखने के लिए क्या है, का $अर्थ है एक पंक्ति का अंत। यह विशिष्ट प्रतिस्थापन पैटर्न का अनुसरण करता है: s/.../.../modifiersकमांड लाइन विकल्प -rखड़ा होता है। विस्तारित रेगेक्स सिंटैक्स (सुविधा की बात के रूप में) और -nइसका मतलब है कि जब तक या जब तक विस्फोटक अनुरोध नहीं किया जाता है तब तक आउटपुट कुछ भी नहीं होता है। pसंशोधक परिणाम को प्रिंट करता है।

आप gसंशोधक के साथ एक वैश्विक खोज कर सकते हैं जैसे:

sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename  # note the space after \1

तो आप एक स्ट्रिंग से अलग कर दिया मिलता है कि ' '(हो सकता है \n, \tया आप जो है) जिसे आप आसानी से संसाधित कर सकें।

दोनों मान्य हैं बशर्ते आपके मान एक पंक्ति के अंत तक समीकरण वर्ण अवधि से पहले हो और एक साधारण "मान" से विचलित होने वाले शब्दार्थ के साथ टिप्पणियों या अन्य वर्णों का पालन न करें।


संपादित करें:

मैं अन्य पदों पर अभी तक यहाँ टिप्पणी नहीं कर सकता। रेखा को इंगित करने के लिए, बस पंक्ति संख्या पास करें, आपके मामले में 3, sआरंभ करने से पहले या उद्धरण चार (ठीक उसी तरह जैसे)।

sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename

कृपया देख लें info sed। उदाहरण के लिए, 3.2 और 4.7 आपके लिए विशेष रुचि रखते हैं।


5
echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost

या यदि आपके पास फ़ाइल में सामग्री है:

sed 's/.*= //' somefile.txt
localhost

ठीक है, लेकिन मैं अपनी फ़ाइल में इस तरह से पढ़ता हूं: sed -n '3p' स्थापना.sh
मर्सर

2
@Mercer - उन अपडेट को देखें जिन्हें मैंने उत्तर में जोड़ा था।
SLM

@ अदम सीमियन - धन्यवाद, लेकिन लाइन नंबर कैसे इंगित करें?
मर्कल

4

आप कट कमांड का उपयोग कर सकते हैं, '=' तक परिधि की स्थापना कर सकते हैं और फिर इस तरह से दूसरे क्षेत्र को प्रिंट कर सकते हैं:

cut -d'=' -f2

3

इसे करने के कई तरीके, आपकी फ़ाइल को देखते हुए कहा जाता है foobar:

के लिए खोज करने के लिए पैटर्न निर्दिष्ट करें:

PAT=POP3_SERVER_NAME

का उपयोग कर निकालें sed

sed -n "/$PAT/p" foobar | sed "s/$PAT = //"

या का उपयोग कर sedऔरcut

sed -n "/$PAT/p" foobar | cut -d' ' -f3

2

लिनक्स / यूनिक्स की सुंदरता यह है कि आमतौर पर किसी चीज़ को पूरा करने के लिए एक से अधिक तरीके होते हैं। Op के मामले में, फ़ाइल से POP सर्वर नाम निकालने के कम से कम चार अलग-अलग तरीके हैं:

  1. grep POP3_SERVER_NAME installation.sh | cut -d'=' -f2
  2. grep POP3_SERVER_NAME installation.sh | awk '{print $3}'
  3. grep POP3_SERVER_NAME installation.sh | sed 's/.*= //'
  4. sed -n 's/^.*POP3_SERVER_NAME = //p' installation.sh
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.