it-swarm.com.de

Schwanz invertieren/alles außer den letzten n Zeilen drucken?

Gibt es eine (POSIX-Befehlszeilen-) Möglichkeit, alle Dateien auszudrucken, ausgenommen die letzten n Zeilen? Im Einzelfall habe ich mehrere Dateien unbekannter Größe, die alle eine Boilerplate-Fußzeile bekannter Größe enthalten, die ich entfernen möchte. Ich habe mich gefragt, ob es bereits ein Dienstprogramm gibt, das dies ausführt, bevor ich es selbst schreibe.

37
Tossrock

Die meisten Versionen von head (1) - GNU, insbesondere abgeleitet, aber nicht von BSD abgeleitet, verfügen über eine Funktion, um dies zu tun. Es wird der Anfang der Datei mit Ausnahme des Endes angezeigt, wenn Sie eine negative Zahl für die Anzahl der zu druckenden Zeilen verwenden.

So wie:

head -n -10 textfile
39
Adam B

Wahrscheinlich weniger effizient als "wc" + "tun Sie die mathematische" + "tail" -Methode, aber einfacher zu sehen:

tail -r file.txt | tail +NUM | tail -r

Dabei ist NUM eine Zahl mehr als die Anzahl der Endzeilen, die Sie entfernen möchten, z. Mit +11 werden alle bis auf die letzten 10 Zeilen gedruckt. Dies funktioniert bei BSD, die die head -n -NUM-Syntax nicht unterstützen.

10
user9645

Das Dienstprogramm head ist Ihr Freund.

Aus der Manpage von head:

-n, --lines=[-]K
     print the first K lines instead of the first 10;
       with the leading `-', print all but the last K lines of each file
6
Confusion

Es gibt keine Standardbefehle, aber Sie können mit awk oder sed einen Puffer ausNZeilen füllen und nach dem Füllen vom Kopf aus drucken. Z.B. mit awk: 

awk -v n=5 '{if(NR>n) print a[NR%n]; a[NR%n]=$0}' file
4
geirha
cat <filename> | head -n -10 # Everything except last 10 lines of a file
cat <filename> | tail -n +10 # Everything except 1st 10 lines of a file
1
Siva Mandadi

Es ist einfach. Sie müssen + zur Anzahl der Zeilen hinzufügen, die Sie vermeiden möchten.

In diesem Beispiel erhalten Sie alle Zeilen mit Ausnahme der ersten 9

schwanz -n +10 Eingabedatei

(ja, nicht die ersten 10 ... weil es anders zählt ... wenn Sie 10 wollen, geben Sie einfach tail -n 11 inputfile ein)

0
user2836704

Wenn die Fußzeile mit einer konsistenten Zeile beginnt, die nicht an anderer Stelle angezeigt wird, können Sie sed verwenden:

sed '/FIRST_LINE_OF_FOOTER/q' filename

Dadurch wird die erste Zeile der Fußzeile gedruckt. wenn du das vermeiden willst:

sed -n '/FIRST_LINE_OF_FOOTER/q;p' filename

Dies könnte robuster sein als das Zählen von Zeilen, wenn sich die Größe der Fußzeile in der Zukunft ändert. (Oder es könnte weniger robust sein, wenn sich die erste Zeile ändert.)

Wenn der Befehl head Ihres Systems head -n -10 nicht unterstützt, können Sie auch die Anzahl der anzuzeigenden Zeilen vorberechnen. Folgendes hängt von der bash-spezifischen Syntax ab:

lines=$(wc -l < filename) ; (( lines -= 10 )) ; head -$lines filename

Beachten Sie, dass die head -NUMBER-Syntax aus Gründen der Rückwärtskompatibilität von einigen Versionen von head unterstützt wird. POSIX erlaubt nur das Formular head -n NUMBER. POSIX erlaubt auch nur, dass das Argument -n eine positive Dezimalzahl ist. head -n 0 ist nicht unbedingt ein No-Op.

Eine POSIX-kompatible Lösung ist:

lines=$(wc -l < filename) ; lines=$(($lines - 10)) ; head -n $lines filename

Wenn Sie sich mit alten Pre-POSIX-Shells befassen müssen, sollten Sie Folgendes in Betracht ziehen:

lines=`wc -l < filename` ; lines=`expr $lines - 10` ; head -n $lines filename

Wenn eine Datei 10 oder weniger Zeilen lang ist, kann dies zu merkwürdigen Aktionen führen.

0
Keith Thompson

tac file.txt | Schwanz + [n + 1] | tac

Diese Antwort ähnelt der von Benutzer9645, vermeidet jedoch den Befehl tail -r, der für viele Systeme ebenfalls keine gültige Option ist. Für ein Beispiel siehe https://ubuntuforums.org/showthread.php?t=1346596&s=4246c451162feff4e519ef2f5cb1a45f&p=8444785#post8444785

Beachten Sie, dass das +1 (in den Klammern) auf dem System benötigt wurde, das ich zum Testen anprobierte, aber es ist möglicherweise nicht auf Ihrem System erforderlich. Um die letzte Zeile zu entfernen, musste ich zwei in die Klammern setzen. Dies hängt wahrscheinlich mit der Tatsache zusammen, dass die letzte Zeile mit regulären Zeilenvorschubzeichen enden muss. Dies macht die letzte Zeile zu einer leeren Zeile. Wenn Sie das nicht tun, kombiniert der Befehl tac die letzten beiden Zeilen. Wenn Sie also die letzte Zeile (oder die erste Zeile mit dem Befehl tail) entfernen, werden tatsächlich die letzten beiden Zeilen entfernt.

Meine Antwort sollte auch die schnellste Lösung sein, die bisher für Systeme aufgeführt wurde, denen die verbesserte Kopfversion fehlt. Ich denke, es ist sowohl die robusteste als auch die schnellste aller aufgelisteten Antworten.

0