Ich möchte Zeilen aus einer Datei ohne Verwendung des tac
Befehls rückwärts drucken . Gibt es eine andere Lösung, um so etwas mit Bash zu tun?
shell
text-processing
jimmij
quelle
quelle
Antworten:
Verwenden
sed
, um zu emulierentac
:quelle
sed
Einzeiler. Siehe "36. Umgekehrte Reihenfolge der Zeilen (Unix-Befehl" tac "emulieren)." in Famous Sed One-Liners Erklärt für eine vollständige Erklärung, wie es funktioniert.sort
- es besteht die Möglichkeit, dass eine temporäre Datei verwendet wird).Mit
ed
:Wenn Sie auf
BSD
/ sindOSX
(und hoffentlich bald auch aufGNU
/linux
wie es POSIX sein wird ):quelle
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt
über awk one liner
quelle
awk 'a=$0RS a{}END{printf a}'
but your first
perl reverse <> `es ist die beste / schnellste Antwort auf der Seite (für mich), 10-mal schneller als dieseawk
Antwort (alle awk Anseres sind ungefähr gleich, zeitlich)awk '{a[NR]=$0} END {while (NR) print a[NR--]}'
Hier ist eine Lösung, die awk, sed oder perl nicht verwendet, sondern nur eine bash-Funktion:
Die Ausgabe von
ist
Wie erwartet.
Achten Sie jedoch darauf, dass die Zeilen im Speicher gespeichert sind, eine Zeile in jeder rekursiv aufgerufenen Instanz der Funktion. So vorsichtig mit großen Dateien.
quelle
Sie können es durchpfeifen:
Das
awk
Präfix jeder Zeile enthält die Zeilennummer, gefolgt von einem Leerzeichen. Diesort
Reihenfolge der Zeilen wird umgekehrt, indem das erste Feld (Zeilennummer) in umgekehrter Reihenfolge im numerischen Stil sortiert wird. Und dersed
Streifen von den Zeilennummern.Das folgende Beispiel zeigt dies in Aktion:
Es gibt aus:
quelle
cat -n
wirkt ähnlich wieawk '{print NR" "$0}'
In Perl:
quelle
perl -e 'print reverse<>'
perl -pe '$\=$_.$\}{'
)reverse<)
ist schnell: gut! Aber die "wirklich hässliche" ist extrem langsam, da die Anzahl der Zeilen erhöht. !! ....-n
war da überflüssig, danke.sort
).Nur-BASH-Lösung
Lies die Datei in das Bash-Array (eine Zeile = ein Element des Arrays) und drucke das Array in umgekehrter Reihenfolge aus:
quelle
while..read
.IFS=''
undread -r
, um zu verhindern, dass alle Arten von Ausbrüchen und nachfolgende IFS-Entfernung es vermasseln. Ich denke, dass die Bash-mapfile ARRAY_NAME
Funktion eine bessere Lösung für das Einlesen in Arrays ist.Bash, mit
mapfile
in Kommentaren erwähntem Fiximan, und eigentlich eine möglicherweise bessere Version:Die Leistung ist im Wesentlichen mit der der
sed
Lösung vergleichbar und wird mit abnehmender Anzahl der angeforderten Leitungen schneller.quelle
quelle
wie hier gezeigt:
Ergebnis:
quelle
quelle