सवाल लिनक्स में टेक्स्ट फ़ाइल से कुछ लाइनों को कैसे प्रदर्शित करें?


मुझे लगता है कि हर कोई उपयोगी लिनक्स सीएमडी लाइन यूटिलिटीज जानता है head तथा tailhead आपको फ़ाइल की पहली एक्स लाइनों को प्रिंट करने की अनुमति देता है, tail वही करता है लेकिन फ़ाइल के अंत को प्रिंट करता है। फ़ाइल के बीच प्रिंट करने के लिए एक अच्छा आदेश क्या है? कुछ इस तरह middle --start 10000000 --count 20 (10'000'000 वें तक 10'000'010 वीं लाइनों तक प्रिंट करें)।

मैं ऐसा कुछ ढूंढ रहा हूं जो बड़ी फाइलों को कुशलतापूर्वक सौदा करेगा। मैंने कोशिश की tail -n 10000000 | head 10 और यह भयानक रूप से धीमा है।


73
2018-04-19 08:53


मूल


के संभावित डुप्लिकेट serverfault.com/questions/101900/... - Kyle Brandt♦


जवाब:


sed -n '10000000,10000020p' filename

आप इसे थोड़ा तेज करने में सक्षम हो सकते हैं:

sed -n '10000000,10000020p; 10000021q' filename

उन आदेशों में, विकल्प -n का कारण बनता है sed "पैटर्न स्थान की स्वचालित प्रिंटिंग दबाने" के लिए। p कमांड "वर्तमान पैटर्न स्पेस प्रिंट करें" और q आदेश "तुरंत किसी भी इनपुट को संसाधित किए बिना sed स्क्रिप्ट [s] छोड़ दें ..." उद्धरण हैं sed  man पृष्ठ

वैसे, आपका आदेश

tail -n 10000000 filename | head 10

से दस मिलियन लाइन पर शुरू होता है समाप्त फ़ाइल का, जबकि आपका "मध्य" कमांड दस मिलियन से शुरू होगा शुरू जो बराबर होगा:

head -n 10000010 filename | tail 10

समस्या यह है कि परिवर्तनीय लंबाई रेखाओं के साथ छोड़ी गई फ़ाइलों के लिए किसी भी प्रक्रिया को नई लाइनों की गिनती फ़ाइल के माध्यम से जाना होगा। शॉर्टकट करने का कोई तरीका नहीं है।

यदि, हालांकि, फ़ाइल को सॉर्ट किया गया है (उदाहरण के लिए टाइमस्टैम्प के साथ एक लॉग फ़ाइल) या लंबाई रेखा तय की गई है, तो आप बाइट स्थिति के आधार पर फ़ाइल में जा सकते हैं। लॉग फ़ाइल उदाहरण में, आप मेरी पायथन लिपि के रूप में कई बार बाइनरी खोज कर सकते हैं यहाँ* कर देता है। निश्चित रिकॉर्ड लंबाई फ़ाइल के मामले में, यह वास्तव में आसान है। तुम बस खोजो linelength * linecount फ़ाइल में अक्षर।

* मैं उस स्क्रिप्ट पर एक और अपडेट पोस्ट करने का अर्थ रखता हूं। हो सकता है कि मैं इन दिनों में से एक के आसपास जाऊंगा।


93
2018-04-19 09:11



यहां है sed चार्ल्स का संस्करण middle समारोह: middle() { local s=$1 c=$2; shift 2; sed -n "$s,$(($s + $c -1))p; $(($s + $c))q" "$@"; }। यह एकाधिक फ़ाइल तर्कों, रिक्त स्थान के साथ फ़ाइल नाम इत्यादि को संभालेगा। एकाधिक फ़ाइलों को एक साथ संसाधित किया जाता है जैसे कि उन्हें उसी तरह से कैट किया गया था sed आम तौर पर करता है (इसलिए मध्य 1000 100 फ़ाइल 1 फ़ाइल 2 दूसरी फ़ाइल की शुरुआत में पहली फ़ाइल के अंत में फैल जाएगा यदि पहले वाले में 1100 से कम लाइनें हों)। - Dennis Williamson
मेरी पिछली टिप्पणी में फ़ंक्शन को फ़ाइल नाम पैरामीटर के साथ बुलाया जा सकता है: middle startline count filename या एकाधिक फ़ाइल नाम: middle startline count file1 file2 file3 या पुनर्निर्देशन के साथ: middle startline count < filename या एक पाइप में: some_command | मध्य स्टार्टलाइन गिनती 'या cat file* | middle startline count - Dennis Williamson
'अपने sed आदेश में' एक नहीं होना चाहिए? मैं इसे बैकटिक के साथ काम नहीं कर सकता लेकिन यह एकल उद्धरण के साथ ठीक काम करता है। - Ian Hunter
@beanland: हाँ, यह एक टाइपो है। मैंने इसे ठीक कर दिया है। धन्यवाद। - Dennis Williamson
@kev: मैंने अपने जवाब में कुछ स्पष्टीकरण जोड़ा। - Dennis Williamson


मुझे निम्नलिखित उपयोग का पता चला sed

sed -n '10000000,+20p'  filename

उम्मीद है कि यह किसी के लिए उपयोगी है!


25
2018-06-17 18:22



यह जानना अच्छा है कि डेनिस द्वारा प्रस्तावित अंतिम पंक्ति तर्क का एक विकल्प है: दूसरी पंक्ति के रूप में एक पंक्ति गणना sed -n तर्क जो इसे काफी पठनीय बनाता है। - user3123159
एक उदाहरण उपयोग: extract_lines(){sed -n "$1,+$2p" <file>} जो stdout लिखता है। - user3123159


यह मेरी पहली बार पोस्टिंग है! वैसे भी, यह एक आसान है। मान लीजिए कि आप file.t72 नामक फ़ाइल से लाइन 8872 खींचना चाहते हैं। इसे कैसे करना है इसके बारे में यहां बताया गया है:

cat -n file.txt | grep '^ * 8872'

अब सवाल यह है कि इसके बाद 20 लाइनें मिलें। इसे पूरा करने के लिए आप करते हैं

cat -n file.txt | grep -A 20 '^ * 8872'

Grep मैन्युअल में -B और -C झंडे को देखने या देखने से पहले लाइनों के लिए।


4
2018-05-23 12:11



हालांकि यह तकनीकी रूप से सही है और इसे एक उचित आकार की फ़ाइल पर करने का एक दिलचस्प तरीका है, लेकिन पोस्टर पूछने वाले आकार की फाइलों के साथ काम करते समय मैं इसकी प्रभावकारिता के बारे में उत्सुक हूं। - Jenny D
एकाधिक पंक्तियां: cat -n file.txt | grep "^ \ s \ + (10 \ | 20 \ | 30) \ s \ +" - Jeff K.
cat -n file.txt | grep '^ *1' उन सभी लाइनों को उपज करें जिनकी दाईं ओर 1 है। इस तकनीक के साथ लाइन 1 आउटपुट कैसे करें? मुझे पता है कि मैं सिर-1 कर सकता हूं .... लेकिन grep का उपयोग कैसे करें? - Sean87


डेनिस 'sed जवाब जाने का रास्ता है। लेकिन केवल सिर और पूंछ का उपयोग करके, बैश के तहत:

मध्य () {head -n $ [$ 1 + $ 2] | पूंछ- $ 2; }

यह पहली बार $ 1 + $ 2 लाइनों को दो बार स्कैन करता है, इसलिए डेनिस के जवाब से भी बदतर है। लेकिन आपको इसका उपयोग करने के लिए उन सभी sed अक्षरों को याद रखने की जरूरत नहीं है ....


1
2018-04-19 15:08



का उपयोग करते हुए $[...] कम से कम बैश में, बहिष्कृत है। साथ ही, आप एक फ़ाइल पैरामीटर खो रहे हैं। - Dennis Williamson
@ डेनिस: कोई गुम पैरामीटर नहीं: आप इसका उपयोग स्टडीन पर करने के लिए कर रहे हैं middle 10 10 < /var/log/auth.log। - Charles Stewart


लाइनों की विशेष श्रृंखला प्राप्त करने के लिए निम्न आदेश का प्रयोग करें

awk 'NR < 1220974{next}1;NR==1513793{exit}' debug.log | tee -a test.log

यहां debug.log मेरी फाइल है जिसमें लाइनों की कमी शामिल है और मैं 1220 9 74 लाइन संख्या से 15137 9 3 तक फाइल test.log पर लाइनों को प्रिंट करता था। उम्मीद है कि यह लाइनों की सीमा को कैप्चर करने में मददगार होगा।


1
2018-04-17 19:48



जैसा ही जवाब है serverfault.com/a/641252/140016। Downvoted। - Deer Hunter
यह वही जवाब नहीं है। यह बड़ी फ़ाइलों के लिए तेज़ होना चाहिए क्योंकि यह फ़ाइल के माध्यम से स्कैनिंग जारी रखने की बजाय अंतिम पंक्ति को प्रिंट करने के बाद वास्तव में बंद हो जाता है। - phobic


एक रूबी ऑनलाइनर संस्करण।

ruby -pe 'next unless $. > 10000000 && $. < 10000020' < filename.txt

यह किसी के लिए उपयोगी हो सकता है। डेनिस और डोक्स द्वारा प्रदान किए गए 'sed' के साथ समाधान बहुत अच्छा है, यहां तक ​​कि क्योंकि यह तेज़ी से लगता है।


0
2018-05-23 12:58





आप 'nl' का उपयोग कर सकते हैं।

nl filename | grep <line_num>

0
2017-10-31 19:35





उदाहरण के लिए यह अजीब 20 और 40 के बीच लाइनों को मुद्रित करेगा

अजीब '{अगर ((एनआर> 20) && (एनआर <40)) $ 0} प्रिंट करें / / etc / passwd


0
2017-10-31 22:02





यदि आप लाइन numebrs पता है, तो आप एक फ़ाइल से लाइन 1, 3 और 5 प्राप्त करना चाहते हैं, कहें / etc / passwd:

perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd

0
2018-03-23 13:36





पर्ल राजा है:

perl -ne 'print if ($. == 10000000 .. $. == 10000020)' filename

0
2018-05-22 12:24