วิธีอ่านบรรทัดแรกและบรรทัดสุดท้ายจากเอาต์พุต cat?


64

ฉันมีไฟล์ข้อความ งาน - รับบรรทัดแรกและบรรทัดสุดท้ายจากไฟล์หลังจาก

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

$ cat file
1
2
3
4
5

ต้องการสิ่งนี้โดยไม่ต้องใช้เอาต์พุต cat (เพียง 1 และ 5)

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

อาจจะมีวิธีแก้ปัญหาที่สั้นลงและสั้นลงกว่าเดิม ...


ในตัวอย่างที่สองของคุณwc -lไม่มีส่วนเกี่ยวข้องกับการแสดงบรรทัดสุดท้ายของไฟล์
David Richerby

คำตอบ:


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

และยังเป็นตัวอย่างของ piped ด้วย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 จะสิ้นสุดลง มิฉะนั้นสำหรับทุกบรรทัดยกเว้นบรรทัดสุดท้ายให้ลบ ในบรรทัดสุดท้าย "พิมพ์" โดยนัยจะเกิดขึ้นอีกครั้ง
เกล็นแจ็คแมน

1
@mikeserv: ;-) ตรวจสอบเมื่อคุณมีโอกาส ในบรรทัดเดียวมันป้องกันการเพิ่มขึ้นสองเท่าในเอาต์พุต แต่ในกรณีทำงานหลายบรรทัดมันแค่เก็บบรรทัดสุดท้าย ... อย่างน้อยใน GNU sed4.2.2 ไชโย
Cbhihe

23

sed -n '1p;$p' file.txt จะพิมพ์บรรทัดที่ 1 และบรรทัดสุดท้ายของ file.txt


10
โปรดทราบว่าหากอินพุตมีเพียงหนึ่งบรรทัดมันจะถูกพิมพ์สองครั้ง คุณอาจต้องการsed -e 1b -e '$!d'ถ้าคุณไม่ต้องการที่
Stéphane Chazelas

10

วิธีBash≥4บริสุทธิ์ตลก:

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

หลังจากนี้คุณจะมีอาร์เรย์aryกับฟิลด์แรก (กล่าวคือมีค่าดัชนี0) เป็นบรรทัดแรกของและสนามสุดท้ายเป็นบรรทัดสุดท้ายของfile fileการเรียกกลับcb(ทางเลือกถ้าคุณต้องการ slurp ทุกบรรทัดในอาร์เรย์) จะยกเลิกการทำเครื่องหมายเส้นกลางทั้งหมดเพื่อไม่ให้หน่วยความจำรกรุงรัง ในฐานะที่เป็นผลพลอยได้ฟรีคุณจะมีจำนวนบรรทัดในไฟล์ (เป็นดัชนีสุดท้ายของอาร์เรย์ + 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เซนต์หนึ่งและไม่ลา$ทีหนึ่ง
ใช้!เพื่อNOT(ปฏิเสธ) เงื่อนไขและX{Y..}โครงสร้างเพื่อรวมX และ Yเงื่อนไข:

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

หรือคุณสามารถใช้ช่วง - จาก2nd ถึง la $t - และลบบรรทัดทั้งหมดในช่วงนั้นยกเว้น$บรรทัดla t:

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

6

ใช้ Perl:

$ 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

@drs ฉันได้แก้ไขคำตอบเพื่อหลีกเลี่ยงการใช้ 'ls' เป็นตัวอย่างอินพุต
dolmen

1
@dolmen: อาจเป็นความคิดที่ดีที่จะแก้ไขให้เสร็จโดยระงับการอ้างอิงทั้งหมดไปยัง / etc ฉันเดาว่ามันถูกเพิ่มเข้ามาหลังจากการแก้ไขครั้งแรกเมื่อปีที่แล้ว แต่เหมือนกันทั้งหมดเพราะมันยืนคำตอบไม่สมเหตุสมผลเลย เพียงข้อเสนอแนะ
Cbhihe

4

ไม่มีแมว:

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

หรือ

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

8
ในคนแรกคำสั่งของเส้นจะไม่รับประกัน
Stéphane Chazelas

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.