Wie gebe ich alle Zeilen außer der letzten aus

Die Idee für diesen Artikel hatte ich, als ich in einem der Blogs sah, dass diese Aufgabe vorgeschlagen wird, den folgenden einzeiligen Code in der Sprache Perl zu lösen:

 echo -e '1\n2\n3' | perl -nalE 'push(@lines, $_); }{ say $lines[$_] foreach 0..$#lines -1'
Und was ist mit dem Dienstprogramm head Fragen Sie mich? Ja, das ist die beste Option. Aber wie sich herausstellt, kann man dieses Dienstprogramm auf einigen Systemen nicht mit einem negativen Wert für den Parameter n verwenden (wenn man nicht weiß, wie viele Zeilen in der Datei sind). Was im ursprünglichen Artikel erwähnt wurde, bevor eine solche Variante der Lösung vorgeschlagen wurde.

Aber wie es mir scheint, gibt es zwei Probleme in diesem Code-snippet:

  1. Zwei Durchgänge werden nach den Daten gemacht. Die erste ist, wenn wir jede Zeile in das array @lines speichern. Und die zweite, wenn wir die gewünschten Zeilen ausgeben
  2. Die gesamte Datei wird im Speicher gespeichert
Also habe ich beschlossen, meine Lösung anzubieten, die solche Probleme nicht hat:
 echo -e '1\n2\n3' | perl -nale 'push(@l, $_); print shift(@l) if @l> 1;'
Der Code ist sehr einfach, aber lassen Sie uns ihn genauer betrachten. Erstens speichern wir nicht die gesamte Datei im Speicher, sondern nur die Anzahl der Zeilen, die wir nicht ausgeben wollen - eine Art Puffer. Zweitens entscheiden wir sofort, ob wir eine Zeile ausgeben oder nicht. Die Anzahl der Zeilen, die wir nicht vom Ende ausgeben, wird durch eine Zahl angegeben. In diesem Beispiel ist es eine einzelne Zeile.

Messungen des verbrauchten Speichers habe ich auf einer 72M-Datei getestet

 ls -lah big.file
 -rw-r--r-- 1 madskill madskill 72M ноя  1 03:56 big.file
Für die erste Option, erhielt die folgenden Werte
 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 23400 madskill  20   0  205844 188952   3960 S   0,0  4,8   0:07.44 perl
Und für meine Option sind die folgenden
 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 23413 madskill  20   0   21056   3492   3248 S   0,0  0,1   0:10.71 perl
Aus den obigen Messungen ist ersichtlich, dass meine Option Speicher sparsamer verwendet. Aber darauf habe ich nicht aufgehört und weiter grob die beiden warints nach der Leistung verglichen. Es stellte sich heraus, dass es fast keinen Unterschied gibt. Bei Neustarts war die eine, die andere Variante schneller. Und der Unterschied zwischen Ihnen war sehr klein.
 time cat big.file | perl -nalE 'push(@lines, $_); }{ say $lines[$_] foreach 0..$#lines -1;'> /dev/null
 real	0m1,789s
 user	0m1,662s
 sys	0m0,188s
 time cat big.file | perl -nale 'push(@l, $_); print shift(@l) if @l> 1;'> /dev/null
 real	0m1,732s
 user	0m1,688s
 sys	0m0,116s