निकालने का एक अच्छा तरीका क्या है, एक विशाल टेक्स्ट फ़ाइल में से 20 -45 लाइनें। गैर-अंतःक्रियात्मक रूप से!
निकालने का एक अच्छा तरीका क्या है, एक विशाल टेक्स्ट फ़ाइल में से 20 -45 लाइनें। गैर-अंतःक्रियात्मक रूप से!
जवाबों:
तुम कोशिश कर सकते हो:
cat textfile | head -n 45 | tail -n 26
या
cat textfile | awk "20 <= NR && NR <= 45"
अपडेट करें:
जैसा कि Mahomedalid ने बताया है, cat
यह आवश्यक नहीं है और थोड़ा बेमानी है, लेकिन यह एक साफ, पठनीय कमांड के लिए बनाता है।
अगर cat
आपको परेशान करता है, तो बेहतर इलाज होगा:
<textfile awk "20 <= NR && NR <= 45"
,
रेंज ऑपरेटर को प्रदर्शित करना था ।
और भी सरल:
sed -n '20,45p;45q' < textfile
-N ध्वज डिफ़ॉल्ट आउटपुट अक्षम करता है। "20,45" पंक्तियों को 20 से 45 तक सम्मिलित करता है। "पी" कमांड वर्तमान लाइन को प्रिंट करता है। और q लाइन को प्रिंट करने के बाद क्विट करता है।
q
कमांड (सब कुछ से शुरू ;
जब एक 27,169,334 लाइन फ़ाइल से एक लाइन 26,995,107 निकालने) मेरे लिए प्रदर्शन में सुधार किया।
यह एक उत्तर नहीं है, लेकिन इसे टिप्पणी के रूप में पोस्ट नहीं किया जा सकता है।
यह करने के लिए एक और (बहुत तेज़) तरीका यहाँ 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
awk NR==1000020,NR==1000045 textfile
आपके सिस्टम में इसके साथ कितना समय लगता है।
ruby -ne 'print if 20 .. 45' file
python -c 'import fileinput, sys; [sys.stdout.write(line) for nr, line in enumerate(fileinput.input()) if 19 <= nr <= 44]'
भी क्यों नहीं ? :-P यह कुछ ऐसा है जो रूबी, पर्ल के बाद मॉडलिंग करता है, जो awk / sed से प्रेरित है, आसानी से कर सकता है।
चूंकि sed और awk पहले ही ले लिए गए थे, यहाँ एक पर्ल समाधान है:
perl -nle "print if ($. > 19 && $. < 46)" < textfile
या, जैसा कि टिप्पणियों में बताया गया है:
perl -ne 'print if 20..45' textfile
perl -ne'print if 20..45' textfile
awk NR==20,NR==45 textfile
भी काम करता है, और आसानी से पढ़ता है।