Gibt es einen Bash-Befehl, mit dem Sie die n-te Zeile von STDOUT abrufen können?
Das heißt, etwas, das dies erfordern würde
$ ls -l
-rw-r--r--@ 1 root wheel my.txt
-rw-r--r--@ 1 root wheel files.txt
-rw-r--r--@ 1 root wheel here.txt
und so etwas tun
$ ls -l | magic-command 2
-rw-r--r--@ 1 root wheel files.txt
Mir ist klar, dass dies eine schlechte Praxis wäre, wenn ich Skripte schreibe, die wiederverwendet werden sollen, 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 dafür einen Standard- Shell-Befehl gibt, der verfügbar wäre, ohne dass ich ein Skript ablegen müsste.
magic-command
Antworten:
Verwenden
sed
, nur für Abwechslung:Die Verwendung dieser Alternative, die effizienter aussieht, da die Eingabe beim Drucken der erforderlichen Zeile nicht mehr gelesen wird, kann beim Zuführvorgang ein SIGPIPE erzeugen, das wiederum eine unerwünschte Fehlermeldung erzeugen kann:
Ich habe das oft genug gesehen, dass ich normalerweise das erste verwende (was sowieso einfacher zu tippen ist), obwohl
ls
es kein Befehl ist, der sich beschwert, wenn es SIGPIPE bekommt.Für eine Reihe von Zeilen:
Für mehrere Linienbereiche:
quelle
p
ist diesed
Anweisung, die die Zeilen druckt, die durch den vorangegangenen Zeilenbereich gekennzeichnet sind . So2,4p
bedeutet Druckzeilen 2, 3, 4.n
bedeutet, NICHT alle anderen Zeilen zu druckenquelle
head -n 2 | tail -n 1
- moderne Köpfe und Schwänze neigen dazu, ansonsten Warnungen auszugeben.head -n M | tail -n M-N+1
), und das Verallgemeinern, um mehrere Bereiche zu behandeln, ist nicht möglich.$ ls -l | awk '{if (NR>=4 && NR<=64) print}'
Alternative zum schönen Kopf / Schwanz-Weg:
oder
quelle
'2p'
?2
es sich um eine Variable handelt? In jedem Beispiel werden einfache Anführungszeichen verwendet, bei einer Variablen benötigen Sie jedoch doppelte Anführungszeichen. Könnten wir awk "programmieren", um auch mit einfachen Anführungszeichen zu arbeiten, wenn wir vars verwenden? Beispielline =1; ls | awk 'NR==$line'
. Ich weiß, dassbash
doppelte Anführungszeichen mit vars verwendet werden.Von sed1line :
Von awk1line :
quelle
Der Vollständigkeit halber ;-)
kürzerer Code
kürzere Lebensdauer
quelle
ls
- die ursprüngliche Frage betraf die von jemandemSTDOUT
, also dachte ich, es ist besser, es größer zu haben.{ print $0 }
, also ist "awk" NR == 3 eine kürzere Möglichkeit, dasselbe zu schreiben.Versuchen Sie diese
sed
Version:Es heißt "alle Zeilen löschen, die nicht die zweite sind".
quelle
Sie können awk verwenden:
Aktualisieren
Der obige Code erhält aufgrund eines Fehleres nach dem anderen nicht das, was wir wollen: Die erste Zeile des Befehls ls -l ist die Gesamtzeile . Dafür funktioniert der folgende überarbeitete Code:
quelle
Ist Perl für Sie leicht verfügbar?
Ersetzen Sie natürlich 7 durch eine beliebige Zahl.
quelle
$ awk 'NR % 7' filename
jede 7. Zeile in der Datei drucken.Ein anderes Poster schlug vor
Wenn Sie jedoch den Kopf in den Schwanz leiten, sieht es so aus, als würde alles bis zur Linie N zweimal verarbeitet.
Schwanz in den Kopf leiten
wäre effizienter?
quelle
Ja, der effizienteste Weg (wie bereits von Jonathan Leffler ausgeführt) ist die Verwendung von sed mit print & quit:
quelle
Hmm
sed hat in meinem Fall nicht funktioniert. Ich schlage vor:
quelle
Für mehr Vollständigkeit ..
Werfen Sie die Zeilen weg, bis Sie zur zweiten gelangen, und drucken Sie danach die erste Zeile aus. Es wird also die 3. Zeile gedruckt.
Wenn es nur die zweite Zeile ist ..
Setzen Sie so viele Lesungen wie nötig.
quelle
Ich habe dies in meinem .bash_profile hinzugefügt
Und es funktioniert
quelle