Jak edytować zawartość ze standardowego wejścia?

15

Chciałbym edytować zawartość w vimie, która została dynamicznie wygenerowana z wiersza poleceń bez posiadania pliku.

W przykładzie:

$ echo This is example. | vim /dev/stdin
$ cat /etc/hosts | vim /dev/stdin

ale nie działa z błędami:

Vim: Ostrzeżenie: Dane wejściowe nie pochodzą z terminala

Vim: Błąd odczytu danych wejściowych, wychodzenie ...

Czy można to osiągnąć?

kenorb
źródło
:help stdin... To niesamowite, jak szybko można znaleźć odpowiedzi, zadając pytanie dotyczące wbudowanej dokumentacji.
dash-tom-bang

Odpowiedzi:

24

Musisz użyć -zamiast nazwy pliku w wierszu poleceń:

echo This is example. | vim -

Powyższe polecenie otworzy nienazwany bufor wypełniony tekstem odczytanym ze standardowego wejścia.

toro2k
źródło
7
Używanie -for stdin jest standardem dla narzędzi wiersza poleceń;
Martin Tournoij
6

To jest po prostu fajna uwaga na temat bashi readline, ale jeśli ustawisz EDITORzmienną środowiskową na vim, naciśnięcie Ctrl+ x+ eotworzy bieżącą linię vim. Ponadto, jeśli wpiszesz Meta(Alt/Opt/Esc)+ Ctrl+ e, bash wykona rozwinięcie w miejscu w bieżącym wierszu poleceń, tj .:

$ echo $EDITOR # Assuming EDITOR was set

z Meta(Alt/Opt/Esc)+ Ctrl+ estałoby się

$ echo vim # Assuming EDITOR was set

z Ctrl+ x+ estałoby się

1 echo vim # Assuming EDITOR was set
~
~
/tmp/sometmpbufferfile

Zauważ, że po wyjściu z vima zawartość bufora vim jest wykonywana w wierszu poleceń.

Funkcje te stają się dla mnie bardzo przydatne, gdy chcę wykonywać polecenia wieloliniowe w trybie bash, takie jak pętle lub programy wymagające tutaj instrukcji, i zapewnia ciekawy sposób zapisania odrobiny historii wiersza poleceń do pliku do późniejszego wykorzystania.

Aby odpowiedzieć na oryginalne pytanie, możesz również napisać:

$ This is an example

a następnie naciśnij Ctrl+ x+, eaby załadować vim. Ty też możesz mieć

 $ $(cat /etc/hosts)

i wykonaj Meta(Alt/Opt/Esc)+ Ctrl+, ea następnie Ctrl+ x+ e, co umieściłoby wszystkie pliki hosts w jednym wierszu i załadowało je vim(prawdopodobnie nie najlepsze wykorzystanie tych funkcji - jednak użyteczność tych metod można ekstrapolować z kilku omówionych przykładów tutaj).

Zauważ, że zakładam, że readlineustawiony jest emacstryb. Jeśli readlineustawiony jest vimtryb, możesz łatwo odkryć odpowiednie powiązania za pomocą polecenia:

bind -p

i wyszukiwanie edit-and-execute-commandlub shell-expand-line, które były odpowiednio powiązane z powiązaniami Ctrl+ x+ ei Meta(Alt/Opt/Esc)+ Ctrl+ e.

HAL 9001
źródło
Możesz nakazać bashowi używanie klawiszy vi zamiast emacsa. Użyj, set -o viaby włączyć. Następnie możesz po prostu użyć vmapowania w trybie normalnym, aby edytować bieżące polecenie w edytorze.
Quincy Bowers
1
Z pewnością jest to świetna sztuczka do edycji wiersza poleceń za pomocą vi, ale istnieją co najmniej dwa problemy przy użyciu tej metody do odczytu tekstu ze standardowego wejścia: 1. shell-expand-lineusuń znaki nowej linii z rozwiniętego tekstu i 2. edit-and-execute-commandspróbuj wykonać polecenie zapisane w buforze , cokolwiek jest zapisane lub nie, po wyjściu z vi.
toro2k
Łał, to jest niesamowite. Codziennie uczę się czegoś nowego o readline ...
Klamka
2

W bashu użyteczne jest stosowanie podstawiania procesów przy użyciu <(command)składni, na przykład:

vim <(echo This is example.)
vim <(cat /etc/hosts)

Zobacz też:

kenorb
źródło
4
Zauważ, że to nie zadziała we wszystkich powłokach. Myślę, że to będzie działać tylko w bashi zsh(a nie sh, ksh, dash, fish, csh, tcsh, itd.)
Martin Tournoij
@Carpetsmoker Powinien działać w ksh88 i nowszych, myślę, ale tak, podstawianie procesów nie jest POSIX.
muru
4
I uważaj, aby się nie oszukać! Kiedy uruchomisz Vima w ten sposób, otworzy bufor dla pliku takiego jak /proc/PID/fd/FD. Jeśli napiszesz bufor i wyjdziesz, Vim nie narzeka, ale plik, do którego napisałeś, zostanie usunięty przez system operacyjny. Użycie -jako nazwy pliku otwartego bufora nie wiąże się z żadnym plikiem, więc jeśli spróbujesz wyjść bez (dopóki nie użyjesz komendy huk lub podobnego), zapisanie Vima cię ostrzeże.
toro2k
1
Jest to miłe, ponieważ dobrze się uogólnia vimdiff <(echo foo) <(echo bar).
wchargin
@ toro2k Aby kontynuować, wygląda na to, że używa :nexti :prevponownie czyta strumień i nic nie dostaje. Warto również wspomnieć, że procesy nie są równoległe względem siebie - np. cat <(sleep 3; echo a) <(echo b)Odbitki w kolejności - i podczas gdy catprzeploty zapisują i odczytują, vimczeka na pliku, aby „zakończyć czytanie”, zanim wyświetli wszystko oprócz ramki zewnętrznej.
John P
-1

Jeśli użycie potoku do nowego Vima nie jest wymagane, możesz użyć zdolności Vima do pobierania danych wyjściowych poleceń do bieżącego bufora, w połączeniu z posiadaniem bufora nieopartego na pliku (tak jak w przypadku :newedytowania nieistniejącego pliku)

:read!cat /etc/hosts w trybie poleceń umieści dane wyjściowe w bieżącym buforze poniżej bieżącej pozycji kursora.

Oprócz konieczności usuwania pustego pierwszego wiersza, który pozostaje, gdy jest to wykonywane w pustym buforze, działa to dobrze i jest szczególnie wygodne, jeśli Vim już działa.

ewatt
źródło
1
Jak to odpowiada na pytanie?
muru
Pobiera dane wyjściowe polecenia i umieszcza je w vimie.
ewatt