it-swarm.com.de

Befehl zum Abrufen der n-ten Zeile von STDOUT

Gibt es einen Bash-Befehl, mit dem Sie die n-te Zeile von STDOUT abrufen können?

Das heißt, etwas, das dies dauern würde

$ ls -l
[email protected] 1 root  wheel my.txt
[email protected] 1 root  wheel files.txt
[email protected] 1 root  wheel here.txt

und mach sowas

$ ls -l | magic-command 2
[email protected] 1 root  wheel files.txt

Mir ist klar, dass dies beim Schreiben von Skripten, die wiederverwendet werden sollen, eine schlechte Praxis wäre, ABER wenn ich Tag für Tag mit der Shell arbeite, wäre es für mich nützlich, mein STDOUT so filtern zu können.

Mir ist auch klar, dass dies ein halbtrivialer Befehl zum Schreiben wäre (Puffer STDOUT, Rückgabe einer bestimmten Zeile), aber ich möchte wissen, ob es einen Standard Shell-Befehl dafür gibt, der verfügbar wäre, ohne dass ich ihn fallen lasse ein Skript an Ort und Stelle.

190
Alan Storm

Mit sed, nur für Abwechslung:

ls -l | sed -n 2p

Die Verwendung dieser Alternative, die effizienter aussieht, da die Eingabe nicht mehr gelesen wird, wenn die erforderliche Zeile gedruckt wird, kann zu einer SIGPIPE im Einzugsprozess führen, die wiederum zu einer unerwünschten Fehlermeldung führen kann:

ls -l | sed -n -e '2{p;q}'

Ich habe das oft genug gesehen, dass ich normalerweise das erste benutze (was ohnehin einfacher zu tippen ist), obwohl ls kein Befehl ist, der sich beschwert, wenn es SIGPIPE bekommt.

Für eine Reihe von Linien:

ls -l | sed -n 2,4p

Für mehrere Linienbereiche:

ls -l | sed -n -e 2,4p -e 20,30p
ls -l | sed -n -e '2,4p;20,30p'
303
ls -l | head -2 | tail -1
79
mob

Alternative zum Nice Head/Tail Way:

ls -al | awk 'NR==2'

oder

ls -al | sed -n '2p'
39
ChristopheD

Von sed1line :

# print line number 52
sed -n '52p'                 # method 1
sed '52!d'                   # method 2
sed '52q;d'                  # method 3, efficient on large files

From awk1line :

# print line number 52
awk 'NR==52'
awk 'NR==52 {print;exit}'          # more efficient on large files
21
Mark Edgar

Der Vollständigkeit halber ;-)

kürzerer Code

find / | awk NR==3

kürzeres Leben

find / | awk 'NR==3 {print $0; exit}'

Sie können awk verwenden:

ls -l | awk 'NR==2'

Aktualisieren

Der obige Code wird nicht das bekommen, was wir wollen, weil ein Fehler vorliegt: Die erste Zeile des ls -l Befehls ist die Summe Linie. Dafür wird der folgende überarbeitete Code funktionieren:

ls -l | awk 'NR==3'
6
Hai Vu

Versuchen Sie diese sed Version:

ls -l | sed '2 ! d'

Es heißt "alle Zeilen löschen, die nicht die zweite sind".

6

Ist Perl für Sie leicht verfügbar?

$ Perl -n -e 'if ($. == 7) { print; exit(0); }'

Ersetzen Sie 7 durch eine beliebige Zahl.

4
catfood

Ein anderes Plakat schlug vor

ls -l | head -2 | tail -1

wenn Sie jedoch den Kopf in den Schwanz leiten, sieht es so aus, als würde alles bis zur Zeile N zweimal verarbeitet.

Schwanz in den Kopf leiten

ls -l | tail -n +2 | head -n1

wäre effizienter?

3
nobody

Ja, der effizienteste Weg (wie bereits von Jonathan Leffler hervorgehoben) ist es, sed mit print & quit zu verwenden:

set -o pipefail                        # cf. help set
time -p ls -l | sed -n -e '2{p;q;}'    # only print the second line & quit (on Mac OS X)
echo "$?: ${PIPESTATUS[*]}"            # cf. man bash | less -p 'PIPESTATUS'
0
mco

Hmm

sed hat in meinem fall nicht funktioniert. Ich schlage vor:

für "ungerade" Zeilen 1,3,5,7 ... ls | awk '0 == (NR + 1)% 2'

für "gerade" Zeilen 2,4,6,8 ls | awk '0 == (NR)% 2'

0
stan