Sie können es mit vim stdinund tun stdout. Sie können auch verwenden , exum POSIX - kompatibel . vimist nur der visuelle Modus für ex. In der Tat können Sie exmit vim -eoder vim -E(verbesserter exModus) verwenden.
vimist nützlich, da im Gegensatz zu ähnlichen Tools seddie Datei zum Bearbeiten gepuffert wird, während sedsie für Streams verwendet wird. Möglicherweise können Sie verwenden awk, aber Sie müssten alles in einer Variablen manuell puffern.
Die Idee ist, Folgendes zu tun:
- Lesen Sie von stdin
- Verschieben Sie es für jede Zeile in Zeile 1 (umkehren). Befehl ist
g/^/m0. Dies bedeutet global für jede Zeile g; Passen Sie den Zeilenanfang an, der mit allem übereinstimmt ^. Verschieben Sie es nach Adresse 0, Zeile 1 m0.
- Alles drucken. Befehl ist
%p. Dies bedeutet für den Bereich aller Linien %; Drucken Sie die Zeile p.
- Beenden Sie gewaltsam, ohne die Datei zu speichern. Befehl ist
q!. Dies bedeutet beenden 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 dies wiederverwendbar macht
Ich benutze ein Skript, das ich aufrufe ved(vim editor like sed), um vim zum Bearbeiten zu verwenden stdin. Fügen Sie dies einer Datei hinzu, die vedin Ihrem Pfad aufgerufen wird:
#!/usr/bin/env sh
vim - --not-a-term -Es "$@" +'%p | q!'
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:
seq 10 | ved +'g/^/m0'
Wenn Sie vim 8 nicht haben, geben Sie vedstattdessen Folgendes ein :
#!/usr/bin/env sh
vim -E "$@" +'%p | q!' /dev/stdin
perl -e 'print reverse <>'aber wahrscheinlich auch für andere Methoden).