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


85

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

मैं एक ऐसी चीज की तलाश कर रहा हूं जो बड़ी फाइलों को कुशलता से निपटाएगी। मैंने कोशिश की tail -n 10000000 | head 10और यह बहुत ही धीमी है।


जवाबों:


111
sed -n '10000000,10000020p' filename

आप इस तरह से थोड़ी गति कर सकते हैं:

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

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

वैसे, आपकी आज्ञा

tail -n 10000000 filename | head 10

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

head -n 10000010 filename | tail 10

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

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

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


यहां sedचार्ल्स के middleसमारोह का एक संस्करण है middle() { local s=$1 c=$2; shift 2; sed -n "$s,$(($s + $c -1))p; $(($s + $c))q" "$@"; }:। यह कई फ़ाइल तर्क, रिक्त स्थान के साथ फ़ाइलनाम आदि को सम्‍मिलित करेगा। एकाधिक फ़ाइलों को एक साथ संसाधित किया जाता है जैसे कि उन्‍हें उसी तरह से क्रेट किया गया हो जैसा कि sedआम तौर पर होता है (इसलिए बीच की 1000 100 file1 file2 शुरुआत में पहली फ़ाइल के अंत में फैलेगी दूसरे वाले अगर पहले वाले के पास 1100 से कम लाइनें हैं)।
डेनिस विलियमसन

मेरी पिछली टिप्पणी में समारोह को एक फ़ाइल नाम पैरामीटर के साथ कहा जा सकता है: middle startline count filenameया कई फ़ाइलनाम: middle startline count file1 file2 file3या पुनर्निर्देशन के साथ: middle startline count < filenameया एक पाइप में: some_command | मध्य शुरुआत काउंटलाइन 'याcat file* | middle startline count
डेनिस विलियमसन

क्या आपके sed कमांड में `a’ नहीं होना चाहिए? मैं इसे बैकटिक के साथ काम करने के लिए नहीं कर सकता, लेकिन यह एकल उद्धरण के साथ ठीक काम करता है।
इयान हंटर

@ बीनलैंड: हां, यह एक टाइपो है। मैंने इसे ठीक कर लिया है। धन्यवाद।
डेनिस विलियमसन

1
@kev: मैंने अपने उत्तर में कुछ स्पष्टीकरण जोड़ा।
डेनिस विलियमसन

28

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

sed -n '10000000,+20p'  filename

आशा है कि यह किसी के लिए उपयोगी है!


यह जानकर अच्छा लगा कि डेनिस द्वारा प्रस्तावित अंतिम लाइन तर्क का एक विकल्प है: एक पंक्ति को दूसरे sed -nतर्क के रूप में गिना जाता है जो इसे काफी पठनीय बनाता है।
user3123159

एक उदाहरण का उपयोग: extract_lines(){sed -n "$1,+$2p" <file>}जो stdout को लिखता है।
user3123159

4

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

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

अब सवाल इसके बाद 20 लाइनों को खोजने का है। इसे पूरा करने के लिए आप

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

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


जबकि यह तकनीकी रूप से सही है और इसे एक उचित आकार की फ़ाइल पर करने का एक दिलचस्प तरीका है, मैं इसकी प्रभावकारिता के बारे में उत्सुक हूं जब पोस्टर के आकार के बारे में फाइलों के साथ काम कर रहा है।
जेनी डी

एकाधिक पंक्तियाँ: cat -n file.txt | grep "^ \ s \ + (10 \ | 20 \ | 30) \ s \ +"
जेफरी नाइट

cat -n file.txt | grep '^ *1'उन सभी रेखाओं को प्राप्त करें जिनकी दाईं ओर 1 है। इस तकनीक के साथ लाइन 1 आउटपुट कैसे करें? मुझे पता है कि मैं 1 सिर कर सकता हूं .... लेकिन grep का उपयोग कैसे करें?
सीन87

1

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

बीच () {सिर -n $ [$ 1 + $ 2] | पूंछ-एन $ 2; }

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


उपयोग $[...]कम से कम बैश में किया जाता है। इसके अलावा, आपको एक फ़ाइल पैरामीटर याद आ रहा है।
डेनिस विलियमसन

@ डेनिस: कोई लापता पैरामीटर नहीं: आप इसका उपयोग स्टड पर, प्रति के अनुसार करने के लिए कर रहे हैं middle 10 10 < /var/log/auth.log
चार्ल्स स्टीवर्ट

1

लाइनों की विशेष श्रेणी प्राप्त करने के लिए निम्नलिखित कमांड का उपयोग करें

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

यहाँ debug.log मेरी फ़ाइल है जिसमें रेखाओं की कमी है और मैं 1220974 लाइन नंबर से 1513793 तक एक फ़ाइल test.log के लिए लाइनों को प्रिंट करता था। आशा है कि यह लाइनों की सीमा पर कब्जा करने के लिए मददगार होगा।


Serverfault.com/a/641252/140016 के रूप में एक ही जवाब । Downvoted।
हिरण हंटर

यह एक ही जवाब नहीं है। यह बड़ी फ़ाइलों के लिए तेज़ होना चाहिए क्योंकि यह वास्तव में फ़ाइल के माध्यम से स्कैनिंग जारी रखने के बजाय अंतिम पंक्ति को प्रिंट करने के बाद गर्भपात करता है।
फोबिक

0

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

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

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


0

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

nl filename | grep <line_num>

0

उदाहरण के लिए यह awk 20 और 40 के बीच की लाइनें प्रिंट करेगा

awk '{if (NR (20> 20) && (NR <40)) $ 0} प्रिंट करें /' आदि / पासवार्ड


0

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

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

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