STDOUT की nth लाइन प्राप्त करने के लिए कमांड


210

क्या कोई बैश कमांड है जो आपको STDOUT की nth लाइन प्राप्त करने देगा?

यह कहना है, कुछ है जो यह ले जाएगा

$ ls -l
-rw-r--r--@ 1 root  wheel my.txt
-rw-r--r--@ 1 root  wheel files.txt
-rw-r--r--@ 1 root  wheel here.txt

और कुछ करो

$ ls -l | magic-command 2
-rw-r--r--@ 1 root  wheel files.txt

मुझे लगता है कि यह बुरा अभ्यास होगा जब स्क्रिप्ट लिखना फिर से उपयोग किया जाना चाहिए, लेकिन जब शेल दिन के साथ काम कर रहा है तो यह मेरे लिए उपयोगी होगा कि मैं अपने STDOUT को इस तरह से फ़िल्टर कर सकूं।

मुझे यह भी महसूस होता है कि यह लिखने के लिए अर्ध-तुच्छ कमांड होगा (बफर STDOUT, एक विशिष्ट लाइन लौटाएं), लेकिन मैं जानना चाहता हूं कि क्या ऐसा करने के लिए कुछ मानक शेल कमांड है जो मेरे लिए जगह में स्क्रिप्ट छोड़ने के बिना उपलब्ध होगी।


5
मैंने सिर्फ शब्द के उपयोग के लिए इसे अप वोट किया हैmagic-command
सेवनवेट्र्स 26'19

जवाबों:


332

का उपयोग कर sed, बस विविधता के लिए:

ls -l | sed -n 2p

इस विकल्प का उपयोग करना, जो कि अधिक कुशल दिखता है क्योंकि यह इनपुट को पढ़ना बंद कर देता है जब आवश्यक लाइन छपी होती है, फीडिंग प्रक्रिया में एक SIGPIPE उत्पन्न हो सकता है, जो बदले में एक अवांछित त्रुटि संदेश उत्पन्न कर सकता है:

ls -l | sed -n -e '2{p;q}'

मैंने देखा है कि अक्सर ऐसा होता है कि मैं आमतौर पर पहले का उपयोग करता हूं (जो कि टाइप करना आसान है, वैसे भी), हालांकि lsयह कमांड नहीं है जो शिकायत करता है जब यह एसआईजीपीईपी हो जाता है।

लाइनों की एक श्रृंखला के लिए:

ls -l | sed -n 2,4p

लाइनों की कई श्रेणियों के लिए:

ls -l | sed -n -e 2,4p -e 20,30p
ls -l | sed -n -e '2,4p;20,30p'

पी का मतलब क्या है? 2p 3p की तरह? इस अर्थ में मैं समझता हूं कि यह 2/3 लाइन के लिए है, लेकिन इसके पीछे सिद्धांत / समझ क्या है?
सिंह उफमीत्सेव

4
@LeoUfimtsev: pहै sedबयान है कि लाइनों की सीमा है कि पछाड़ यह द्वारा लाइनों की पहचान की प्रिंट करता है। इस प्रकार 2,4pप्रिंट लाइनें 2, 3, 4. का अर्थ है
जोनाथन लेफ़लर

3
और nअन्य सभी पंक्तियों को न छापने का अर्थ है
तिमो

85
ls -l | head -2 | tail -1

13
+2, लेकिन मेरा सुझाव है कि head -n 2 | tail -n 1- आधुनिक प्रमुख और पूंछ अन्यथा चेतावनी जारी करते हैं।
माइकल क्रेलिन - हैकर

2
डेटा को फ़िल्टर करने के लिए दो प्रक्रियाओं का उपयोग करना थोड़ा अधिक है (लेकिन, इन दिनों मशीनों की शक्ति को देखते हुए, वे संभवतः सामना करेंगे)। एक सीमा को संभालने के लिए सामान्य बनाना पूरी तरह से तुच्छ नहीं है (सीमा एन। एम। के लिए, आप उपयोग करते हैं head -n M | tail -n M-N+1), और कई श्रेणियों को संभालने के लिए सामान्यीकरण संभव नहीं है।
जोनाथन लेफ्लर

3
पूंछ में सिर फंसाया? भयानक। इसे करने के कई बेहतर तरीके।
कैम

16
महान बात के बारे में * निक्स कमांड लाइन: एक लाख और सब कुछ करने के लिए एक तरीका है और हर किसी का पसंदीदा है और सभी अन्य तरीकों से नफरत करता है ... :-)
भिखारियों

1
किसी अन्य तरीके की लाइनों को कैसे प्रिंट करें: $ ls -l | awk '{if (NR>=4 && NR<=64) print}'(अधिक स्थितियों को आसान, एकाधिक श्रेणी, आदि जोड़ सकते हैं ...)
user10607

41

अच्छा सिर / पूंछ के लिए वैकल्पिक:

ls -al | awk 'NR==2'

या

ls -al | sed -n '2p'

1
मेरा awk बेहतर है, लेकिन sed अच्छा है।
माइकल क्रेलिन - हैकर

"अगर" के लिए कोई ज़रूरत नहीं है - हैकर का उत्तर देखें ( सिस्टम पर हर फ़ाइल को खोजने के बारे में भाग को छोड़कर )। ;-)
अगली सूचना तक रोक दिया गया।

क्या '2p'खड़ा है?
shredding

1
@ उत्तर संक्षिप्त प्रिंट दूसरी पंक्ति; लंबी -> जब उपयोग किया जाता है, तो पैटर्न से मेल खाने वाली रेखाओं को पते के बाद कमांड दी जाती है। संक्षेप में, जब / p ध्वज के साथ उपयोग किया जाता है, तो मिलान लाइनें दो बार मुद्रित होती हैं: sed '/ PATTERN / p' फ़ाइल। और निश्चित रूप से PATTERN किसी भी नियमित अभिव्यक्ति अधिक है
Medhat

क्या है अगर 2एक चर है? हर उदाहरण एकल उद्धरण का उपयोग करता है, लेकिन एक संस्करण के साथ आपको दोहरे उद्धरण चिह्नों की आवश्यकता होती है। जब हम vars का उपयोग करते हुए सिंगल कोट्स के साथ काम करने के लिए "प्रोग्राम" जाग सकते हैं? उदाहरण है line =1; ls | awk 'NR==$line'। मुझे पता है कि bashvar के साथ दोहरे उद्धरण का उपयोग करता है।
टिमो


9

परिपूर्णता के लिए ;-)

छोटा कोड

find / | awk NR==3

छोटा जीवन

find / | awk 'NR==3 {print $0; exit}'

आप पूर्णता के बारे में मजाक नहीं कर रहे हैं!
अगली सूचना तक रोक दिया गया।

मैं नहीं; ;-) असल में, मुझे पता है कि हर किसी का उपयोग क्यों होता है ls- मूल प्रश्न किसी के बारे में था STDOUT, इसलिए मैंने सोचा कि इसे बड़ा करना बेहतर है।
माइकल क्रेलिन -

कम से कम GNU awk के साथ, डिफ़ॉल्ट क्रिया है { print $0 }, इसलिए `awk 'NR == 3 एक समान लिखने का एक छोटा तरीका है।
एफ़ेमिएंट

आपको संभवतः उस क्रिया में "बाहर निकलें" जोड़ना चाहिए। जब आप उनके साथ कुछ भी नहीं करने जा रहे हैं तो कोई भी बात बाकी लाइनों को प्रोसेस नहीं करती है।
कैम

@camh: उसके बारे में जोनाथन लेफ़र का जवाब देखें: "खिला प्रक्रिया में एक SIGPIPE उत्पन्न हो सकता है, जो एक अवांछित त्रुटि संदेश उत्पन्न कर सकता है"।
अपरिपक्व


6

आप awk का उपयोग कर सकते हैं:

ls -l | awk 'NR==2'

अपडेट करें

उपरोक्त कोड से वह नहीं मिलेगा जो हम ऑफ-बाय-वन एरर के कारण चाहते हैं: ls -l कमांड की पहली लाइन कुल लाइन है। उसके लिए, निम्न संशोधित कोड काम करेगा:

ls -l | awk 'NR==3'

4

क्या पर्ल आसानी से आपके लिए उपलब्ध है?

$ perl -n -e 'if ($. == 7) { print; exit(0); }'

7 के लिए जो भी नंबर चाहिए उसे स्पष्ट रूप से स्थानापन्न करें।


यह मेरा fav है क्योंकि यह मुझे लगता है कि मैं व्यक्तिगत रूप से हर nth, perl -n -e 'अगर ($।% 7 == 0) {प्रिंट के बाद सामान्यीकृत करने के लिए सबसे आसान लगता है ; बाहर निकलने के (0); } '
चटाई kelcey

@matkelcey आप $ awk 'NR % 7' filenameहर 7 वीं पंक्ति को फाइल में प्रिंट करने के लिए भी कर सकते हैं ।
user10607

3

एक और पोस्टर सुझाया

ls -l | head -2 | tail -1

लेकिन अगर आप पूंछ में सिर रखते हैं, तो ऐसा लगता है कि लाइन एन तक सब कुछ दो बार संसाधित होता है।

सर में पूंछ बाँधना

ls -l | tail -n +2 | head -n1

अधिक कुशल होगा?


0

हाँ, सबसे कुशल तरीका (जैसा कि पहले से ही जोनाथन लेफ़लर द्वारा बताया गया है) प्रिंट और छोड़ के साथ sed का उपयोग करना है:

set -o pipefail                        # cf. help set
time -p ls -l | sed -n -e '2{p;q;}'    # only print the second line & quit (on Mac OS X)
echo "$?: ${PIPESTATUS[*]}"            # cf. man bash | less -p 'PIPESTATUS'

पिपीफेल और पिपेस्टैटस का उपयोग बहुत दिलचस्प है और यह इस पृष्ठ पर बहुत कुछ जोड़ता है।
माइक एस

0

हम्म

मेरे मामले में sed ने काम नहीं किया। मैंने प्रस्ताव रखा है:

"विषम" लाइनों के लिए 1,3,5,7 ... ls | awk '0 == (NR + 1)% 2'

"सम" लाइनों के लिए 2,4,6,8 ls। awk '0 == (NR)% 2'


-1

अधिक पूर्णता के लिए ।।

ls -l | (for ((x=0;x<2;x++)) ; do read ; done ; head -n1)

जब तक आप दूसरी तक न पहुंचें, तब तक लाइनों को फेंक दें, उसके बाद पहली पंक्ति का प्रिंट आउट लें। तो, यह तीसरी लाइन को प्रिंट करता है।

अगर यह सिर्फ दूसरी पंक्ति है ..

ls -l | (read; head -n1)

जितना हो सके उतना पढ़ें ’।


-1

मैंने इसे अपने .bash_profile में जोड़ा

function gdf(){
  DELETE_FILE_PATH=$(git log --diff-filter=D --summary | grep delete | grep $1 | awk '{print $4}')
  SHA=$(git log --all -- $DELETE_FILE_PATH | grep commit | head -n 1 | awk '{print $2}')
  git show $SHA -- $DELETE_FILE_PATH
}

और यह काम करता है

gdf <file name>

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