Sie können dies tun mit vim
stdin
et stdout
. Sie können auch verwenden ex
zu sein POSIX-konform . vim
ist nur der visuelle Modus für ex
. In der Tat, Sie können ex
con vim -e
o vim -E
(verbessert ex
Modus). vim
ist nützlich, denn im Gegensatz zu Tools wie sed
wird die Datei zur Bearbeitung gepuffert, während sed
wird für Streams verwendet. Sie können möglicherweise Folgendes verwenden awk
aber Sie müssten alles manuell in einer Variablen zwischenspeichern.
Die Idee ist, Folgendes zu tun:
- Lesen von stdin
- Verschieben Sie jede Zeile auf Zeile 1 (zum Umkehren). Der Befehl lautet
g/^/m0
. Dies bedeutet global für jede Zeile g
; passt auf den Anfang der Zeile, der auf alles passt ^
nach Adresse 0, also nach Zeile 1, verschieben m0
.
- Drucken Sie alles aus. Der Befehl lautet
%p
. Dies bedeutet für den Bereich aller Linien %
; die Zeile drucken p
.
-
Zwangsweise Beendigung ohne Speichern der Datei. Befehl ist q!
. Das heißt, kündigen q
kraftvoll !
.
Generate a newline delimited sequence of 1 to 10
$ seq 10
1
2
3
4
5
6
7
8
9
10
Use - to read from stdin.
vim has a delay and annoying 'Vim: Reading from stdin...' output
if you use - to read from stdin. Use --not-a-term to hide output.
--not-a-term requires vim 8.0.1308 (Nov 2017)
Use -E for improved ex mode. -e would work here too since I'm not
using any improved ex mode features.
each of the commands I explained above are specified with a + sign
and are run sequentially.
$ seq 10 | vim - --not-a-term -Es +'g/^/m0' +'%p' +'q!'
10
9
8
7
6
5
4
3
2
1
non improved ex mode works here too, -e.
$ seq 10 | vim - --not-a-term -es +'g/^/m0' +'%p' +'q!'
If you don't have --not-a-term, use /dev/stdin
seq 10 | vim -E +'g/^/m0' +'%p' +'q!' /dev/stdin
POSIX compliant (maybe)
POSIX compliant ex doesn't allow using + sign to specify commands.
It also might not allow running multiple commands sequentially.
The docs say "Implementations may support more than a single -c"
If yours does support multiple -c
$ seq 10 | ex -c "execute -c 'g/^/m0' -c '%p' -c 'q!' /dev/stdin
If not, you can chain them with the bar, |. This is same as shell
piping. It's more like shell semi-colon, ;.
The g command consumes the |, so you can use execute to prevent that.
Not sure if execute and | is POSIX compliant.
seq 10 | ex -c "execute 'g/^/m0' | %p | q!" /dev/stdin
Wie man sie wiederverwendbar macht
Ich verwende ein Skript mit der Bezeichnung ved
(Vim-Editor wie sed
), um vim zum Bearbeiten zu verwenden stdin
. Fügen Sie dies zu einer Datei namens ved
auf Ihrem Weg:
#!/usr/bin/env sh
vim - --not-a-term -Es "$@" +'%p | q!'
Ich benutze eine +
Befehl anstelle von +'%p' +'q!'
weil Vim Sie auf 10 Befehle beschränkt. Wenn man sie also zusammenführt, kann die "$@"
9 zu haben +
Befehle anstelle von 8.
Dann können Sie das tun:
seq 10 | ved +'g/^/m0'
Wenn Sie vim 8 nicht haben, geben Sie Folgendes ein ved
stattdessen:
#!/usr/bin/env sh
vim -E "$@" +'%p | q!' /dev/stdin
8 Stimmen
Wichtiger Hinweis zum Vertauschen der Linien: Vergewissern Sie sich, dass Ihre Datei einen abschließenden Zeilenumbruch enthält. Erstens. Andernfalls werden die letzten beiden Zeilen einer Eingabedatei in einer Ausgabedatei zu einer Zeile zusammengefügt (zumindest bei Verwendung der Option
perl -e 'print reverse <>'
aber das gilt wahrscheinlich auch für andere Methoden).1 Stimmen
Mögliche Duplikate von Wie kann man Zeilen einer Textdatei umkehren?
0 Stimmen
Außerdem ist es fast ein Duplikat (wenn auch älter) von unix.stackexchange.com/questions/9356/ . Wie in diesem Fall ist eine Migration zu unix.stackexchange.com wahrscheinlich angebracht.