Wie lese ich die erste und letzte Zeile der Cat-Ausgabe?

Wie lese ich die erste und letzte Zeile der Cat-Ausgabe?

Ich habe eine Textdatei. Aufgabe - erste und letzte Zeile aus der Datei abrufen nach

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

$ cat file
1
2
3
4
5

Benötige dies ohne Cat-Ausgabe (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 ...

Antwort1

sedLösung:

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

Beim Auslesen stdinsähe das beispielsweise so aus 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 & SchwanzLösung:

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

Wenn Daten von einem Befehl kommen ( 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

awkLösung:

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

Und auch das Piped-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}

Antwort2

sed -n '1p;$p' file.txtdruckt die erste und letzte Zeile von file.txt.

Antwort3

Eine lustige reine Bash≥4-Methode:

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

Danach haben Sie ein Array, arydessen erstes Feld (also mit Index 0) die erste Zeile von ist fileund dessen letztes Feld die letzte Zeile von ist file. Der Rückruf cb(optional, wenn Sie alle Zeilen im Array auslesen möchten) setzt alle Zwischenzeilen zurück, um den Speicher nicht zu überladen. Als kostenloses 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='()'

Antwort4

Ohne Katze:

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

oder

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

verwandte Informationen