Wie lese ich die erste und letzte Zeile der Katzenausgabe?


64

Ich habe eine Textdatei. Aufgabe - erste und letzte Zeile aus Datei nachher holen

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

$ cat file
1
2
3
4
5

Benötige dies ohne Katzenausgang (nur 1 und 5).

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

Vielleicht gibt es awk und eine kürzere Lösung ...


In Ihrem zweiten Beispiel wc -lhat dies nichts mit der Ausgabe der letzten Zeile einer Datei zu tun.
David Richerby

Antworten:


115

sed Lösung:

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

Beim Lesen von, stdinwenn wie folgt aussehen würde (zum Beispiel 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

Kopf & Schwanz Lösung:

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

Wenn Daten von einem Befehl ( ps -ef) kommen:

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 Lösung:

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

Und auch das Pipe-Beispiel mit 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
Danke! Es ist die beste Antwort, weil ich keinen (head -n1 file;tail -n1 file)sehr großen Befehl und keine Pipe als letztes Symbol habe. Also | sed '1p;$!d'kürzer.
Dienstag,

Entschuldigung für mein Englisch, wenn du mich nicht verstehst - es ist mein Problem - erzähl mir davon und ich bereite eine bessere Präsentation für dich vor.
dmgl

7
Funktioniert das head && tailwirklich für dich? seq 10 | (head -n1 && tail -n1)druckt 1nur.
Glenn Jackman

1
@DavidConrad, um zu erläutern, was das Chaos gesagt hat. -e 1b- Verzweigen Sie in der ersten Zeile zum Ende des sed-Skripts, an welchem ​​Punkt das implizite "Drucken" stattfindet. Wenn die Eingabe nur eine Zeile lang ist, endet sed. Andernfalls löschen Sie alle Zeilen mit Ausnahme der letzten. In der letzten Zeile wird das implizite "Drucken" erneut ausgeführt.
Glenn Jackman

1
@mikeserv: ;-) überprüfe es, wenn du eine Chance hast. Auf einer einzelnen Zeile verhindert es effektiv, dass sie bei der Ausgabe verdoppelt wird, aber auf einem mehrzeiligen Workcase wird nur die letzte Zeile beibehalten ... zumindest unter GNU sed4.2.2. Prost.
Cbhihe

23

sed -n '1p;$p' file.txt Gibt die erste und letzte Zeile der Datei file.txt aus.


10
Beachten Sie, dass die Eingabe, wenn sie nur eine Zeile enthält, zweimal gedruckt wird. Sie können es vorziehen, sed -e 1b -e '$!d'wenn Sie das nicht wollen.
Stéphane Chazelas

10

Ein lustiger purer Bash≥4 Weg:

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

Danach haben Sie ein Array, aryin dem das erste Feld (dh der Index 0) die erste Zeile fileund das letzte Feld die letzte Zeile von ist file. Der Rückruf cb(optional, wenn Sie alle Zeilen im Array schlürfen möchten) setzt alle Zwischenzeilen zurück, um den Speicher nicht zu überfrachten. Als freies Nebenprodukt haben Sie auch die Anzahl der Zeilen in der Datei (als letzter Index des Arrays + 1).

Demo:

$ 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

Mit sedIhnen können dLinien , wenn ÉLETE NICHT die 1st ein UND NICHT der la $t ein.
Verwenden Sie !diese NOTOption, um eine Bedingung zu negieren, und das X{Y..}Konstrukt, um X AND- Y Bedingungen zu kombinieren :

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

Oder Sie können einen Bereich von 2nd bis la $t verwenden und alle Zeilen in diesem Bereich mit Ausnahme der $Zeile la t löschen :

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

6

Perl benutzen:

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

Das obige druckt den ersten Eintrag in der Ausgabe von seq 10über if 1..1, während das or eofauch den letzten Eintrag druckt.


3
Können Sie erklären, wie das funktioniert? Bitte vermeiden Sie es, solche einzeiligen Antworten zu geben, ohne zu erklären, was sie tun und wie.
Terdon

1
was tun /etc abrtund yum.repos.dhaben diese frage zu tun?
drs

@drs Ich habe die Antwort bearbeitet, um die Verwendung von 'ls' als Beispieleingabe zu vermeiden.
Dolmen

1
@dolmen: Möglicherweise ist es eine gute Idee, die Bearbeitung zu beenden, indem Sie alle Verweise auf / etc unterdrücken. Ich denke, das wurde nach der ersten Bearbeitung hinzugefügt, aber so wie es aussieht, ergibt die Antwort überhaupt keinen Sinn. Nur ein Vorschlag.
Cbhihe

4

Ohne Katze:

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

oder

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

8
In der ersten ist die Reihenfolge der Zeilen nicht garantiert.
Stéphane Chazelas

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.