कैट आउटपुट से पहली और अंतिम पंक्ति कैसे पढ़ें?


64

मेरे पास टेक्स्ट फाइल है। कार्य - फ़ाइल के बाद पहली और अंतिम पंक्ति प्राप्त करें

$ cat file | grep -E "1|2|3|4" | commandtoprint

$ cat file
1
2
3
4
5

बिल्ली के आउटपुट (केवल 1 और 5) के बिना इसकी आवश्यकता है।

~$ cat file | tee >(head -n 1) >(wc -l)
1
2
3
4
5
5
1

शायद awk और अधिक छोटे समाधान मौजूद हैं ...


आपके दूसरे उदाहरण में, wc -lफ़ाइल की अंतिम पंक्ति को आउटपुट करने से कोई लेना-देना नहीं है।
डेविड रिचीर्बी

जवाबों:


115

sed समाधान:

sed -e 1b -e '$!d' file

यदि पढ़ने से stdinयदि ऐसा लगेगा (उदाहरण के लिए ps -ef):

ps -ef | sed -e 1b -e '$!d'
UID        PID  PPID  C STIME TTY          TIME CMD
root      1931  1837  0 20:05 pts/0    00:00:00 sed -e 1b -e $!d

सिर और पूंछ समाधान:

(head -n1 && tail -n1) <file

जब डेटा एक कमांड से आ रहा है ( ps -ef):

ps -ef 2>&1 | (head -n1 && tail -n1)
UID        PID  PPID  C STIME TTY          TIME CMD
root      2068  1837  0 20:13 pts/0    00:00:00 -bash

awk सॉल्यूशन:

awk 'NR==1; END{print}' file

और यह भी उदाहरण के साथ ps -ef:

ps -ef | awk 'NR==1; END{print}'
UID        PID  PPID  C STIME TTY          TIME CMD
root      1935  1837  0 20:07 pts/0    00:00:00 awk NR==1; END{print}

1
धन्यवाद! यह सबसे अच्छा जवाब है क्योंकि मैं ऐसा नहीं कर सकता कि (head -n1 file;tail -n1 file)मेरे पास अंतिम प्रतीक के रूप में बहुत बड़ी कमांड और पाइप है। इतना | sed '1p;$!d'छोटा।
dmgl

मेरी अंग्रेजी के लिए क्षमा करें, यदि आप मुझे नहीं समझते हैं - यह मेरी समस्या है - मुझे इसके बारे में बताएं और मैं आपके लिए बेहतर प्रस्तुति तैयार करूं।
dmgl

7
क्या head && tailवास्तव में आपके लिए काम करता है ? केवल seq 10 | (head -n1 && tail -n1)प्रिंट 1करता है।
ग्लेन जैकमैन

1
@DavidConrad ने अराजकता के बारे में विस्तार से बताया कि, -e 1b- पहली पंक्ति में, sed स्क्रिप्ट के अंत में शाखा, जिस बिंदु पर निहित "प्रिंट" होता है। यदि इनपुट केवल एक पंक्ति लंबी है, तो sed समाप्त होता है। अन्यथा, अंतिम को छोड़कर सभी लाइनों के लिए, हटाएं। अंतिम पंक्ति पर, निहित "प्रिंट" फिर से होता है।
ग्लेन जैकमैन

1
@ बाइक:;; जब आपको मौका मिलता है, तो इसकी जांच करें। एक पंक्ति में यह प्रभावशाली रूप से इसे आउटपुट पर दोहरीकरण से रोकता है, लेकिन कई लाइन कार्य-मामले पर, यह अंतिम पंक्ति को संरक्षित करता है ... कम से कम जीएनयू sed4.2.2 पर। चीयर्स।
Cbhihe

23

sed -n '1p;$p' file.txt file.txt की पहली और आखिरी लाइन प्रिंट करेगा।


10
ध्यान दें कि यदि इनपुट में केवल एक पंक्ति है, तो इसे दो बार मुद्रित किया जाएगा। sed -e 1b -e '$!d'यदि आप ऐसा नहीं चाहते हैं तो आप पसंद कर सकते हैं ।
स्टीफन चेज़लस

10

एक अजीब शुद्ध Bash funny4 रास्ता:

cb() { (($1-1>0)) && unset "ary[$1-1]"; }
mapfile -t -C cb -c 1 ary < file

इसके बाद, आपके पास aryपहले फ़ील्ड के साथ एक सरणी (यानी, इंडेक्स के साथ 0) की पहली पंक्ति होगी file, और इसके अंतिम फ़ील्ड की अंतिम पंक्ति होगी file। कॉलबैक cb(वैकल्पिक यदि आप सरणी में सभी पंक्तियों को तिरछा करना चाहते हैं) सभी मध्यवर्ती लाइनों को अनसेट करता है ताकि अव्यवस्था स्मृति न हो। एक नि: शुल्क उप-उत्पाद के रूप में, आपके पास फ़ाइल में लाइनों की संख्या (सरणी के अंतिम सूचकांक + 1 के रूप में) भी होगी।

डेमो:

$ mapfile -t -C cb -c 1 ary < <(printf '%s\n' {a..z})
$ declare -p ary
declare -a ary='([0]="a" [25]="z")'
$ # With only one line
$ mapfile -t -C cb -c 1 ary < <(printf '%s\n' "only one line")
$ declare -p ary
declare -a ary='([0]="only one line")'
$ # With an empty file
$ mapfile -t -C cb -c 1 ary < <(:)
declare -a ary='()'

7

साथ sedआप सकता है dलाइनों हटाएं यदि नहीं1 सेंट एक न कि ला $टी एक। एक शर्त और संयोजन और शर्तों के लिए (नकारात्मक) का
उपयोग करें :!NOTX{Y..}X Y

cmd | sed '1!{$!d;}'

या आप एक सीमा का उपयोग कर सकते हैं - 2nd से la $t तक - और उस श्रेणी की सभी पंक्तियों को la $t लाइन को छोड़कर हटा सकते हैं :

cmd | sed '2,${$!d;}'

6

पर्ल का उपयोग करना:

$ seq 10 |  perl -ne 'print if 1..1 or eof'
1
10

उपरोक्त आइटम के seq 10माध्यम से आउटपुट के पहले आइटम को प्रिंट करता है if 1..1, जबकि or eofअंतिम आइटम को भी प्रिंट करेगा।


3
क्या आप बता सकते हैं कि यह कैसे काम करता है? कृपया इस बात के स्पष्टीकरण के बिना कि वे क्या करते हैं और कैसे करते हैं, इस तरह के एक-लाइनर उत्तर देने से बचें।
terdon

1
इस सवाल का क्या करना है /etc abrtऔर क्या करना है yum.repos.d?
डीआरएस

@drs मैंने नमूना इनपुट के रूप में 'ls' का उपयोग करने से बचने के लिए उत्तर संपादित किया।
डॉल्मेन

1
@ डोलमेन: / / आदि के लिए सभी संदर्भों को दबाकर संपादन समाप्त करने के लिए एक अच्छा विचार हो सकता है। मुझे लगता है कि yr को पहले संपादित करने के बाद ऐसा जोड़ा गया था, लेकिन, सभी एक ही, जैसा कि इसका उत्तर है कि इसका कोई मतलब नहीं है। केवल एक सलाह।
सेभे

4

बिल्ली के बिना:

$ cat file |tee >(head -n1) >(tail -n1) >/dev/null
1
5

या

$ (head -n1 file;tail -n1 file)
1
5

8
पहले एक में, लाइनों के क्रम की गारंटी नहीं है।
स्टीफन चेज़लस

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