टेक्स्ट फ़ाइल से सेगमेंट लेने का सबसे अच्छा तरीका क्या है?


जवाबों:


12

तुम कोशिश कर सकते हो:

cat textfile | head -n 45 | tail -n 26

या

cat textfile | awk "20 <= NR && NR <= 45" 

अपडेट करें:

जैसा कि Mahomedalid ने बताया है, catयह आवश्यक नहीं है और थोड़ा बेमानी है, लेकिन यह एक साफ, पठनीय कमांड के लिए बनाता है।

अगर catआपको परेशान करता है, तो बेहतर इलाज होगा:

<textfile awk "20 <= NR && NR <= 45"

2
awk NR==20,NR==45 textfileभी काम करता है, और आसानी से पढ़ता है।
अपरिपक्व

मैं स्टड का उपयोग अधिक पसंद करता हूं, इसमें निक्स के बाकी हिस्सों के साथ कुछ वैश्विक संगति है
स्टीफन

1
कमांड लाइन के तर्कों से पढ़ने से अन्य UNIX उपयोगिताओं के साथ भी स्थिरता होती है, और मेरा मुख्य बिंदु awk के ,रेंज ऑपरेटर को प्रदर्शित करना था ।
१२

योग्य, मेरा मतलब @adam है। लेकिन हां, मुझे आपका सुझाव पसंद है
स्टीफन

मुझे लगता है कि @ ephemient का उत्तर यहां सबसे अच्छा है। अन्यथा, कमांड्स क्रिप्टिक हैं।
लेओ लेपोल्ड हर्ट्ज़ o

13

और भी सरल:

sed -n '20,45p;45q' < textfile

-N ध्वज डिफ़ॉल्ट आउटपुट अक्षम करता है। "20,45" पंक्तियों को 20 से 45 तक सम्मिलित करता है। "पी" कमांड वर्तमान लाइन को प्रिंट करता है। और q लाइन को प्रिंट करने के बाद क्विट करता है।


1
+1 अच्छा, मुझे पसंद है, लेकिन इसकी लाइन 20 से 45 :)
स्टीफन

1
ठीक है, मैंने इसे 20,45 :-) कहने के लिए संपादित किया
dkagedal

निकाला जा रहा है qकमांड (सब कुछ से शुरू ;जब एक 27,169,334 लाइन फ़ाइल से एक लाइन 26,995,107 निकालने) मेरे लिए प्रदर्शन में सुधार किया।
रुस्लान

6

यह एक उत्तर नहीं है, लेकिन इसे टिप्पणी के रूप में पोस्ट नहीं किया जा सकता है।

यह करने के लिए एक और (बहुत तेज़) तरीका यहाँ mikeserv द्वारा सुझाया गया था :

{ head -n 19 >/dev/null; head -n 26; } <infile

यहाँ और उसी प्रक्रिया के समान परीक्षण फ़ाइल का उपयोग करते हुए , यहाँ कुछ बेंचमार्क (लाइनें निकाल रहे हैं 1000020-1000045):

mikeserv :

{ head -n 1000019 >/dev/null; head -n 26; } <iplist

real    0m0.059s

स्टीफन :

head iplist -n 1000045 | tail -n 26

real    0m0.054s

ये अब तक के सबसे तेज़ समाधान हैं और अंतर नगण्य हैं (एक पास के लिए) (मैंने विभिन्न श्रेणियों के साथ कोशिश की: कुछ पंक्तियाँ, लाखों लाइनें आदि)।

पाइप के बिना इसे करने से एक महत्वपूर्ण लाभ मिल सकता है, हालांकि, एक ऐसे आवेदन की आवश्यकता होती है , जो इसी तरह की कई पंक्तियों में कई लाइनों की तलाश करना चाहिए , जैसे:

for  pass in 0 1 2 3 4 5 6 7 8 9
do   printf "pass#$pass:\t"
     head -n99 >&3; head -n1
done <<1000LINES 3>/dev/null
$(seq 1000)
1000LINES

... जो प्रिंट करता है ...

pass#0: 100
pass#1: 200
pass#2: 300
pass#3: 400
pass#4: 500
pass#5: 600
pass#6: 700
pass#7: 800
pass#8: 900
pass#9: 1000

... और केवल एक समय के माध्यम से फ़ाइल पढ़ता है।


अन्य sed/ awk/ perlसमाधान पूरी फ़ाइल पढ़ते हैं और चूंकि यह बहुत बड़ी फ़ाइलों के बारे में है, वे बहुत कुशल नहीं हैं। मैं कुछ विकल्पों में फेंक दिया है exitया qनिर्दिष्ट सीमा में अंतिम पंक्ति के बाद uit:

स्टीफन :

awk "1000020 <= NR && NR <= 1000045" iplist

real    0m2.448s

बनाम

awk "NR >= 1000020;NR==1000045{exit}" iplist

real    0m0.243s

डक्रेडल ( sed):

sed -n 1000020,1000045p iplist

real    0m0.947s

बनाम

sed '1,1000019d;1000045q' iplist

real    0m0.143s

स्टीवन डी :

perl -ne 'print if 1000020..1000045' iplist

real    0m2.041s

बनाम

perl -ne 'print if $. >= 1000020; exit if $. >= 1000045;' iplist

real    0m0.369s

+1 मुझे लगता है कि यह यहाँ सबसे अच्छा जवाब है! यह अच्छा होगा कि awk NR==1000020,NR==1000045 textfileआपके सिस्टम में इसके साथ कितना समय लगता है।
Léo Léopold Hertz

3
ruby -ne 'print if 20 .. 45' file

1
एक साथी माणिकवादी, आपको मेरा वोट मिल जाता है
स्टीफन

1
जब हम उस पर हैं, तो python -c 'import fileinput, sys; [sys.stdout.write(line) for nr, line in enumerate(fileinput.input()) if 19 <= nr <= 44]'भी क्यों नहीं ? :-P यह कुछ ऐसा है जो रूबी, पर्ल के बाद मॉडलिंग करता है, जो awk / sed से प्रेरित है, आसानी से कर सकता है।
१२

2

चूंकि sed और awk पहले ही ले लिए गए थे, यहाँ एक पर्ल समाधान है:

perl -nle "print if ($. > 19 && $. < 46)" < textfile

या, जैसा कि टिप्पणियों में बताया गया है:

perl -ne 'print if 20..45' textfile

2
उन सभी अतिरिक्त पात्रों के साथ क्या है? न्यूलाइन को स्ट्रिप और री-ऐड करने की जरूरत नहीं है, लाइन नंबर की तुलना में फ्लिप-फ्लॉप मानता है, और यदि उपलब्ध कराया जाए तो डायमंड ऑपरेटर तर्क के माध्यम से चलता है। perl -ne'print if 20..45' textfile
ईपीडिएंट

1
अच्छा लगा। -लेकिन मुझे लगता है कि एक पलटा हुआ है, बाकी के लिए, मेरे पास अज्ञानता को बचाने का कोई बहाना नहीं है।
स्टीवन डी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.