Und wenn Sie aus irgendeinem Grund Rohre verwenden müssen, dann wie folgt:
cat file.txt |(head; tail)
Hinweis: Gibt doppelte Zeilen aus, wenn die Anzahl der Zeilen in file.txt kleiner ist als die Standardzeilen des Kopfes + die Standardzeilen des Endes.
Genau genommen erhalten Sie nicht das Ende der Originaldatei, sondern das Ende des Streams, nachdem headdie ersten 10 Zeilen der Datei verbraucht wurden. (Vergleichen Sie dies mit head < file.txt; tail < file.txteiner Datei mit weniger als 20 Zeilen). Nur ein sehr kleiner Punkt zu beachten. (Aber immer noch +1.)
Chepper
15
Nett. Wenn Sie eine Lücke zwischen den Kopf- und Schwanzteilen wünschen: (Kopf; Echo; Schwanz) <file.txt
@nametal Eigentlich bekommst du vielleicht gar nicht so viel. Während headnur die ersten 10 Zeilen der Eingabe angezeigt werden, kann nicht garantiert werden, dass nicht mehr davon verbraucht wurden, um das Ende der 10. Zeile zu finden, sodass weniger Eingabe für lessdie Anzeige übrig bleibt .
Chepper
20
Tut mir leid zu sagen, aber die Antwort funktioniert nur in einigen Fällen. seq 100 | (head; tail)gibt mir nur die ersten 10 Zahlen. Nur bei viel größeren Eingaben (wie seq 2000) erhält der Schwanz eine Eingabe.
Was ist, wenn die Datei mehr oder weniger als 200 Zeilen enthält? Und Sie kennen die Anzahl der Zeilen von Anfang an nicht?
Paul
@ Paul Ich habe geändert sedzued
kev
14
Für einen reinen Stream (z. B. Ausgabe eines Befehls) können Sie 'tee' verwenden, um den Stream zu teilen und einen Stream an head und einen an tail zu senden. Dies erfordert die Verwendung der Funktion '> (Liste)' von bash (+ / dev / fd / N):
( COMMAND | tee /dev/fd/3| head )3>>( tail )
oder mit / dev / fd / N (oder / dev / stderr) plus Subshells mit komplizierter Umleitung:
(( seq 1100| tee /dev/fd/2| head 1>&3)2>&1| tail )3>&1(( seq 1100| tee /dev/stderr | head 1>&3)2>&1| tail )3>&1
(Beides funktioniert nicht in csh oder tcsh.)
Für etwas mit etwas besserer Kontrolle können Sie diesen Perl-Befehl verwenden:
COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
+1 für Stream-Unterstützung. Sie könnten stderr wiederverwenden:COMMAND | { tee >(head >&2) | tail; } |& other_commands
jfs
2
Übrigens wird es für Dateien unterbrochen, die größer als die Puffergröße sind (8 KB auf meinem System). cat >/dev/nullbehebt es:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
jfs
Ich war begeistert von der Lösung, aber nach dem Spiel für aa während ich bemerkte , dass der Schwanz in einigen Fällen vor dem Kopf hatte ... Es sind keine Bestellung garantiert zwischen headund tailBefehle: \ ...
Jan
7
(sed -u 10q; echo ...; tail)< file.txt
Nur eine weitere Variation des (head;tail)Themas, aber Vermeidung des anfänglichen Problems der Pufferfüllung für kleine Dateien.
Schön, ich habe immer catund headoder tailgepfeift, gut zu wissen, dass ich sie einzeln verwenden kann!
Paul
Wie kann ich dann diese ersten 10 + letzten 10 in einen anderen Befehl weiterleiten?
Toop
1
@Paul - mit 'your_program' als wc -l gibt es 10 statt 20 zurück
toop
3
oder, ohne eine Unterschale erzeugen zu müssen: { head file; tail file; } | prog(Abstand innerhalb der Klammern und das
nachfolgende
1
Wow ... eine Abwertung für eine Antwort, die anderen sehr ähnlich ist (aber vor ihnen mit einem Zeitstempel versehen ist), von jemandem, der sich entschieden hat, nicht zu posten, warum er abgewählt hat. Nett!
Das Problem hierbei ist, dass Stream-orientierte Programme die Länge der Datei nicht im Voraus kennen (da es möglicherweise keine gibt, wenn es sich um einen echten Stream handelt).
Tools wie tailPuffern Sie die letzten n Zeilen und warten Sie auf das Ende des Streams. Drucken Sie dann.
Wenn Sie dies in einem einzigen Befehl tun möchten (und es mit einem beliebigen Versatz arbeiten lassen und keine Zeilen wiederholen, wenn sie sich überschneiden), müssen Sie dieses erwähnte Verhalten emulieren.
versuche das awk:
awk -v offset=10'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' yourfile
Es braucht mehr Arbeit, um Probleme zu vermeiden, wenn der Versatz größer als die Datei ist
Samus_
Ja, dies funktioniert mit Piped-Ausgabe, nicht nur Dateien: a.out | awk -v ...
Camille Goudeseune
in der Tat :) aber das ist das normale Verhalten von awk. Die meisten Befehlszeilenprogramme arbeiten mit stdin, wenn sie ohne Argumente aufgerufen werden.
Samus_
1
Sehr nahe am gewünschten Verhalten, aber es scheint, dass für <10 Zeilen zusätzliche neue Zeilen hinzugefügt werden.
Sorin
3
Es hat viel Zeit gekostet, diese Lösung zu finden, die (bisher) die einzige zu sein scheint, die alle Anwendungsfälle abdeckt:
Live-Ausgabe für Kopf (offensichtlich ist dies für Schwanz nicht möglich)
Keine Verwendung externer Dateien
Fortschrittsbalken ein Punkt für jede Zeile nach MAX_LINES, sehr nützlich für lange laufende Aufgaben.
Fortschrittsbalken auf stderr, um sicherzustellen, dass die Fortschrittspunkte von Kopf + Schwanz getrennt sind (sehr praktisch, wenn Sie stdout leiten möchten)
vermeidet mögliche falsche Protokollierungsreihenfolge aufgrund von Pufferung (stdbuf)
Vermeiden Sie doppelte Ausgaben, wenn die Gesamtzahl der Zeilen kleiner als Kopf + Schwanz ist.
Ich habe eine Weile nach dieser Lösung gesucht. Ich habe es selbst mit sed versucht, aber das Problem, die Länge der Datei / des Streams vorher nicht zu kennen, war unüberwindbar. Von allen oben verfügbaren Optionen gefällt mir die awk-Lösung von Camille Goudeseune. Er machte sich eine Notiz, dass seine Lösung zusätzliche Leerzeilen in der Ausgabe mit einem ausreichend kleinen Datensatz hinterließ. Hier stelle ich eine Modifikation seiner Lösung zur Verfügung, die die zusätzlichen Zeilen entfernt.
headtail(){ awk -v offset="$1"'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { a_count=0; for (i in a) {a_count++}; for (i=NR-a_count+1; i<=NR; i++) print a[i] }';}
Nun, Sie können sie immer miteinander verketten. Wie so ,
head fiename_foo && tail filename_foo. Wenn dies nicht ausreicht, können Sie sich eine Bash-Funktion in Ihre .profile-Datei oder eine von Ihnen verwendete Anmeldedatei schreiben:
head_and_tail(){
head $1 && tail $1
}
Rufen Sie es später über Ihre Shell-Eingabeaufforderung auf : head_and_tail filename_foo.
Warum cat verwenden, wenn Sie nur head -10 file.txt aufrufen können?
Jstarek
Können Sie die Anzahl der Zeilen variabel machen, sodass der Aufruf ungefähr so lautet: head_ tail (foo, m, n) - Rückgabe der ersten m und der letzten n Textzeilen?
Ricardo
@ricardo, bei dem ein Bash-Skript geschrieben wird, das 3 Argumente benötigt und diese durch Aliasing an tailund / headoder eine Funktion übergibt .
Dies funktioniert für Dateien bekannter Länge, jedoch nicht für Dateien, deren Länge unbekannt ist.
Kevin
0
Fügen Sie Folgendes zu Ihrer .bashrc- oder .profile-Datei hinzu, um Pipes (Streams) sowie Dateien zu verarbeiten:
headtail(){ awk -v offset="$1"'{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }';}
Dann kannst du nicht nur
headtail 10< file.txt
aber auch
a.out | headtail 10
(Dies fügt immer noch unechte Leerzeilen hinzu, wenn 10 die Länge der Eingabe überschreitet, im Gegensatz zu einfach alt a.out | (head; tail). Vielen Dank, frühere Antwortende.)
Aufbauend auf was @Samus_ erklärt hier , wie @Aleksandra Zalcman der Befehl funktioniert, ist diese Variante praktisch , wenn Sie nicht schnell erkennen können , wo der Schwanz ohne Zähllinien beginnt.
Ich würde sagen, dass es abhängig von der Größe der Datei möglicherweise nicht wünschenswert ist, den Inhalt aktiv einzulesen. Unter diesen Umständen denke ich, dass ein einfaches Shell-Scripting ausreichen sollte.
So habe ich dies kürzlich für eine Reihe sehr großer CSV-Dateien gehandhabt, die ich analysiert habe:
$ for file in*.csv;do echo "### ${file}"&& head ${file}&& echo ...&& tail ${file}&& echo;done
Dies druckt die ersten 10 Zeilen und die letzten 10 Zeilen jeder Datei aus, während gleichzeitig der Dateiname und einige Auslassungspunkte vorher und nachher ausgedruckt werden.
Für eine einzelne große Datei können Sie einfach Folgendes ausführen, um den gleichen Effekt zu erzielen:
$ head somefile.csv && echo ...&& tail somefile.csv
Antworten:
Sie können einfach:
Und wenn Sie aus irgendeinem Grund Rohre verwenden müssen, dann wie folgt:
Hinweis: Gibt doppelte Zeilen aus, wenn die Anzahl der Zeilen in file.txt kleiner ist als die Standardzeilen des Kopfes + die Standardzeilen des Endes.
quelle
head
die ersten 10 Zeilen der Datei verbraucht wurden. (Vergleichen Sie dies mithead < file.txt; tail < file.txt
einer Datei mit weniger als 20 Zeilen). Nur ein sehr kleiner Punkt zu beachten. (Aber immer noch +1.)head
nur die ersten 10 Zeilen der Eingabe angezeigt werden, kann nicht garantiert werden, dass nicht mehr davon verbraucht wurden, um das Ende der 10. Zeile zu finden, sodass weniger Eingabe fürless
die Anzeige übrig bleibt .seq 100 | (head; tail)
gibt mir nur die ersten 10 Zahlen. Nur bei viel größeren Eingaben (wieseq 2000
) erhält der Schwanz eine Eingabe.ed
ist derstandard text editor
quelle
sed
zued
Für einen reinen Stream (z. B. Ausgabe eines Befehls) können Sie 'tee' verwenden, um den Stream zu teilen und einen Stream an head und einen an tail zu senden. Dies erfordert die Verwendung der Funktion '> (Liste)' von bash (+ / dev / fd / N):
oder mit / dev / fd / N (oder / dev / stderr) plus Subshells mit komplizierter Umleitung:
(Beides funktioniert nicht in csh oder tcsh.)
Für etwas mit etwas besserer Kontrolle können Sie diesen Perl-Befehl verwenden:
quelle
COMMAND | { tee >(head >&2) | tail; } |& other_commands
cat >/dev/null
behebt es:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
head
undtail
Befehle: \ ...Nur eine weitere Variation des
(head;tail)
Themas, aber Vermeidung des anfänglichen Problems der Pufferfüllung für kleine Dateien.quelle
head -10 file.txt; tail -10 file.txt
Ansonsten müssen Sie Ihr eigenes Programm / Skript schreiben.
quelle
cat
undhead
odertail
gepfeift, gut zu wissen, dass ich sie einzeln verwenden kann!{ head file; tail file; } | prog
(Abstand innerhalb der Klammern und dasBasierend auf dem Kommentar von JF Sebastian :
Auf diese Weise können Sie die erste Zeile und den Rest in einer Pipe unterschiedlich verarbeiten. Dies ist nützlich für die Arbeit mit CSV-Daten:
quelle
Das Problem hierbei ist, dass Stream-orientierte Programme die Länge der Datei nicht im Voraus kennen (da es möglicherweise keine gibt, wenn es sich um einen echten Stream handelt).
Tools wie
tail
Puffern Sie die letzten n Zeilen und warten Sie auf das Ende des Streams. Drucken Sie dann.Wenn Sie dies in einem einzigen Befehl tun möchten (und es mit einem beliebigen Versatz arbeiten lassen und keine Zeilen wiederholen, wenn sie sich überschneiden), müssen Sie dieses erwähnte Verhalten emulieren.
versuche das awk:
quelle
a.out | awk -v ...
Es hat viel Zeit gekostet, diese Lösung zu finden, die (bisher) die einzige zu sein scheint, die alle Anwendungsfälle abdeckt:
Funktionsliste:
quelle
Ich habe eine Weile nach dieser Lösung gesucht. Ich habe es selbst mit sed versucht, aber das Problem, die Länge der Datei / des Streams vorher nicht zu kennen, war unüberwindbar. Von allen oben verfügbaren Optionen gefällt mir die awk-Lösung von Camille Goudeseune. Er machte sich eine Notiz, dass seine Lösung zusätzliche Leerzeilen in der Ausgabe mit einem ausreichend kleinen Datensatz hinterließ. Hier stelle ich eine Modifikation seiner Lösung zur Verfügung, die die zusätzlichen Zeilen entfernt.
quelle
Nun, Sie können sie immer miteinander verketten. Wie so ,
head fiename_foo && tail filename_foo
. Wenn dies nicht ausreicht, können Sie sich eine Bash-Funktion in Ihre .profile-Datei oder eine von Ihnen verwendete Anmeldedatei schreiben:Rufen Sie es später über Ihre Shell-Eingabeaufforderung auf :
head_and_tail filename_foo
.quelle
Erste 10 Zeilen von file.ext, dann die letzten 10 Zeilen:
cat file.ext | head -10 && cat file.ext | tail -10
Letzte 10 Zeilen der Datei, dann die ersten 10:
cat file.ext | tail -10 && cat file.ext | head -10
Sie können die Ausgabe dann auch an eine andere Stelle weiterleiten:
(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program
quelle
tail
und /head
oder eine Funktion übergibt .Ich habe dazu eine einfache Python-App geschrieben: https://gist.github.com/garyvdm/9970522
Es behandelt sowohl Pipes (Streams) als auch Dateien.
quelle
auf die obigen Ideen zurückgreifen (getestete bash & zsh)
aber mit einem Alias "Hut" Kopf und Schwanz
quelle
Warum nicht
sed
für diese Aufgabe verwenden?sed -n -e 1,+9p -e 190,+9p textfile.txt
quelle
Fügen Sie Folgendes zu Ihrer .bashrc- oder .profile-Datei hinzu, um Pipes (Streams) sowie Dateien zu verarbeiten:
Dann kannst du nicht nur
aber auch
(Dies fügt immer noch unechte Leerzeilen hinzu, wenn 10 die Länge der Eingabe überschreitet, im Gegensatz zu einfach alt
a.out | (head; tail)
. Vielen Dank, frühere Antwortende.)Hinweis:
headtail 10
nichtheadtail -10
.quelle
Aufbauend auf was @Samus_ erklärt hier , wie @Aleksandra Zalcman der Befehl funktioniert, ist diese Variante praktisch , wenn Sie nicht schnell erkennen können , wo der Schwanz ohne Zähllinien beginnt.
Wenn Sie mit etwas anderem als 20 Zeilen arbeiten, kann eine Zeilenanzahl sogar hilfreich sein.
quelle
Gehen Sie folgendermaßen vor, um die ersten 10 und letzten 10 Zeilen einer Datei zu drucken:
cat <(head -n10 file.txt) <(tail -n10 file.txt) | less
quelle
HINWEIS : Die Variable aFile enthält den vollständigen Pfad der Datei .
quelle
Ich würde sagen, dass es abhängig von der Größe der Datei möglicherweise nicht wünschenswert ist, den Inhalt aktiv einzulesen. Unter diesen Umständen denke ich, dass ein einfaches Shell-Scripting ausreichen sollte.
So habe ich dies kürzlich für eine Reihe sehr großer CSV-Dateien gehandhabt, die ich analysiert habe:
Dies druckt die ersten 10 Zeilen und die letzten 10 Zeilen jeder Datei aus, während gleichzeitig der Dateiname und einige Auslassungspunkte vorher und nachher ausgedruckt werden.
Für eine einzelne große Datei können Sie einfach Folgendes ausführen, um den gleichen Effekt zu erzielen:
quelle
Verbraucht Standard, aber einfach und funktioniert für 99% der Anwendungsfälle
head_and_tail
Beispiel
quelle