Sie können es mit vim
stdin
und tun stdout
. Sie können auch verwenden , ex
um POSIX - kompatibel . vim
ist nur der visuelle Modus für ex
. In der Tat können Sie ex
mit vim -e
oder vim -E
(verbesserter ex
Modus) verwenden.
vim
ist nützlich, da im Gegensatz zu ähnlichen Tools sed
die Datei zum Bearbeiten gepuffert wird, während sed
sie 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 ved
in 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 ved
stattdessen Folgendes ein :
#!/usr/bin/env sh
vim -E "$@" +'%p | q!' /dev/stdin
perl -e 'print reverse <>'
aber wahrscheinlich auch für andere Methoden).