Ich möchte die Reihenfolge der Zeilen in einer Textdatei (oder stdin) umkehren und den Inhalt jeder Zeile beibehalten.
Also, beginnend mit:
foo
bar
baz
Ich würde gerne mit enden
baz
bar
foo
Gibt es dafür ein Standard-UNIX-Befehlszeilenprogramm?
shell
unix
command-line
Scotty Allen
quelle
quelle
perl -e 'print reverse <>'
aber wahrscheinlich auch für andere Methoden).Antworten:
BSD Schwanz:
Referenz: FreeBSD- , NetBSD- , OpenBSD- und OS X- Handbuchseiten.
quelle
Erwähnenswert sind auch:
tac
(the, ahem, reverse ofcat
). Ein Teil der Coreutils .Eine Datei in eine andere spiegeln
quelle
brew install coreutils
installieren (gtac
wird standardmäßig installiert ).echo -n "abc\ndee" > test; tac test
.Es gibt die bekannten Sed-Tricks :
(Erläuterung: Stellen Sie eine nicht initiale Zeile voran, um den Puffer zu halten, tauschen Sie die Zeile und halten Sie den Puffer, und drucken Sie die Zeile am Ende aus.)
Alternativ (mit schnellerer Ausführung) von den awk-Einzeilern :
Wenn Sie sich nicht daran erinnern können,
Auf einem System mit GNU-Dienstprogrammen sind die anderen Antworten einfacher, aber nicht die ganze Welt ist GNU / Linux ...
quelle
tail -r
und tac.tac
wird erwartet, dass beliebig große Dateien verarbeitet werden, die nicht in den Speicher passen (die Zeilenlänge ist jedoch immer noch begrenzt). Es ist unklar, ob diesed
Lösung für solche Dateien funktioniert.Am Ende Ihres Befehls setzen Sie:
| tac
tac macht genau das, wonach Sie fragen: "Schreiben Sie jede DATEI in die Standardausgabe, letzte Zeile zuerst."
Tac ist das Gegenteil von Katze :-).
quelle
tac
Befehls. Dies ist nützlich für neue Benutzer, die möglicherweise nach demselben Thema suchen.Wenn Sie gerade in
vim
Gebrauch sindquelle
Beispiel:
quelle
Versuchen Sie
tac
, was unter Linux funktioniert, und wenn das nicht funktioniert, verwenden Sietail -r
, was unter BSD und OSX funktioniert.quelle
tac myfile.txt
- was fehlt mir?tail -r
fallstac
es nicht verfügbar ist.tac
ist nicht POSIX-konform. Weder isttail -r
. Immer noch nicht narrensicher, aber dies verbessert die Chancen, dass Dinge funktionieren.tac
es verfügbar ist, aber nicht genügend RAM zur Verfügung steht und auf halbem Weg einen riesigen Eingabestream verbraucht ? Es schlägt fehl und estail -r
gelingt dann , den Rest des Streams zu verarbeiten, was zu einem falschen Ergebnis führt.brew install coreutils
und verwenden Siegtac
anstelle vontac
und wenn Sie es vorziehen, fügen Sie tac als Alias hinzu,gtac
wenn Sie beispielsweise ein Shell-SkriptVersuchen Sie den folgenden Befehl:
quelle
sed 's/^[0-9]*://g'
nl
standardmäßig keine leeren Zeilen nummerieren. Die-ba
Option ist auf einigen Systemen verfügbar und nicht universell (HP / UX fällt mir ein, obwohl ich es nicht wünschte), währendgrep -n
immer jede Zeile nummeriert wird , die dem (in diesem Fall leeren) regulären Ausdruck entspricht.cut -d: -f2-
Just Bash :) (4.0+)
quelle
-nenenenenenene
und sehen Sie, warum die Leute empfehlen, immerprintf '%s\n'
statt zu verwendenecho
.Die einfachste Methode ist die Verwendung des
tac
Befehls.tac
istcat
umgekehrt. Beispiel:quelle
Ich mag die Antwort " tail -r " wirklich , aber meine Lieblingsantwort ist ...
quelle
mawk
unter Ubuntu 14.04 LTS - funktioniert, ist also nicht GNU awk-spezifisch. +1n++
kann ersetzt werden durchNR
BEARBEITEN Folgendes generiert eine zufällig sortierte Liste von Zahlen von 1 bis 10:
Dabei werden Punkte durch den tatsächlichen Befehl ersetzt, der die Liste umkehrt
tac
Python: Verwenden von [:: - 1] auf sys.stdin
quelle
Verwenden Sie für Cross-OS-Lösungen (dh OSX, Linux), die möglicherweise
tac
in einem Shell-Skript verwendet werden, Homebrew, wie andere oben erwähnt haben, und verwenden Sie dann einfach den Alias tac wie folgt:Installieren Sie lib
Für MacOS
Für Linux Debian
Fügen Sie dann einen Alias hinzu
quelle
Dies funktioniert sowohl bei BSD als auch bei GNU.
quelle
Wenn Sie die vorhandene Datei ändern möchten, können Sie sie ausführen
Dadurch entfällt die Notwendigkeit, eine temporäre Datei zu erstellen und dann das Original zu löschen oder umzubenennen. Dies führt zum gleichen Ergebnis. Zum Beispiel:
Basierend auf der Antwort von Ephemient , die fast, aber nicht ganz das tat, was ich wollte.
quelle
Es passiert mir, dass ich die letzten
n
Zeilen einer sehr großen Textdatei effizient abrufen möchte .Das erste, was ich versucht habe, ist
tail -n 10000000 file.txt > ans.txt
, aber ich fand es sehr langsam, denn ichtail
muss nach dem Ort suchen und gehe dann zurück, um die Ergebnisse zu drucken.Wenn ich es merke, wechsle ich zu einer anderen Lösung :
tac file.txt | head -n 10000000 > ans.txt
. Dieses Mal muss sich die Suchposition nur vom Ende zum gewünschten Ort bewegen und das spart 50% Zeit !Nachricht zum Mitnehmen:
Verwenden
tac file.txt | head -n n
Sietail
diese-r
Option, wenn Sie die Option nicht haben .quelle
Beste Lösung:
quelle
Für Emacs-Benutzer:
C-x h
(Wählen Sie die gesamte Datei aus) und dannM-x reverse-region
. Funktioniert auch nur zum Auswählen von Teilen oder Linien und zum Zurücksetzen dieser.quelle
Ich sehe viele interessante Ideen. Aber versuche meine Idee. Geben Sie Ihren Text ein:
Dies setzt voraus, dass das Zeichen '~' nicht in der Datei enthalten ist. Dies sollte auf jeder UNIX-Shell funktionieren, die bis 1961 zurückreicht. Oder so ähnlich.
quelle
Ich hatte die gleiche Frage, aber ich wollte auch, dass die erste Zeile (Kopfzeile) oben bleibt. Also musste ich die Kraft von awk nutzen
PS funktioniert auch in Cygwin oder Gitbash
quelle
1\n20\n19...2\n
eher zu führen als20\n19...\2\n1\n
.Sie können es mit
vim
stdin
und tunstdout
. Sie können auch verwenden ,ex
um POSIX - kompatibel .vim
ist nur der visuelle Modus fürex
. In der Tat können Sieex
mitvim -e
odervim -E
(verbesserterex
Modus) verwenden.vim
ist nützlich, da im Gegensatz zu ähnlichen Toolssed
die Datei zum Bearbeiten gepuffert wird, währendsed
sie für Streams verwendet wird. Möglicherweise können Sie verwendenawk
, aber Sie müssten alles in einer Variablen manuell puffern.Die Idee ist, Folgendes zu tun:
g/^/m0
. Dies bedeutet global für jede Zeileg
; Passen Sie den Zeilenanfang an, der mit allem übereinstimmt^
. Verschieben Sie es nach Adresse 0, Zeile 1m0
.%p
. Dies bedeutet für den Bereich aller Linien%
; Drucken Sie die Zeilep
.q!
. Dies bedeutet beendenq
; kraftvoll!
.Wie man dies wiederverwendbar macht
Ich benutze ein Skript, das ich aufrufe
ved
(vim editor likesed
), um vim zum Bearbeiten zu verwendenstdin
. Fügen Sie dies einer Datei hinzu, dieved
in Ihrem Pfad aufgerufen wird:Ich verwende einen
+
Befehl anstelle von+'%p' +'q!'
, weil vim Sie auf 10 Befehle beschränkt. Wenn Sie sie also zusammenführen, können Sie"$@"
9+
statt 8 Befehle verwenden.Dann können Sie tun:
Wenn Sie vim 8 nicht haben, geben Sie
ved
stattdessen Folgendes ein :quelle
oder
oder
quelle
tail -r funktioniert in den meisten Linux- und MacOS-Systemen
seq 1 20 | Schwanz -r
quelle
oder
quelle
sort -r
funktioniert nur, wenn die Eingabe bereits sortiert ist, was hier nicht der Fall ist.rev
kehrt die Zeichen pro Zeile um, behält aber die Zeilenreihenfolge bei, was auch nicht das ist, wonach Scotty gefragt hat. Diese Antwort ist also überhaupt keine Antwort.