Як редагувати вміст зі стандартного вводу?


15

Я хотів би відредагувати вміст vim, який динамічно генерувався з командного рядка, але файл ще не мав.

Наприклад:

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

але це не вдається з помилками:

Vim: Попередження: Введення не з терміналу

Vim: Помилка читання входу, вихід ...

Цього можна досягти?


:help stdin... Дивно, як швидко можна знайти відповіді, задавши питання про вбудовану документацію.
dash-tom-bang

Відповіді:


24

Ви повинні використовувати -замість імені файлу в командному рядку:

echo This is example. | vim -

Вищевказана команда відкриє неназваний буфер, заповнений текстом, прочитаним зі стандартного вводу.


7
Використання -для stdin - це майже стандарт для інструментів командного рядка;
Мартін Турноїй

6

Це тільки в основному кумедна замітка про bashта readline, але якщо ви встановите EDITORзмінну оточення vim, ударяти Ctrl+ x+ eвідкриє поточний рядок в vim. Далі, якщо ви введете Meta(Alt/Opt/Esc)+ Ctrl+ e, bash виконає розширення на місці в поточному командному рядку, тобто:

$ echo $EDITOR # Assuming EDITOR was set

з Meta(Alt/Opt/Esc)+ Ctrl+ eстане

$ echo vim # Assuming EDITOR was set

з Ctrl+ x+ eстане

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

Зауважте, що після виходу з vim вміст буфера vim виконується в командному рядку.

Ці функції стають для мене дуже корисними, коли я хочу робити багаторядкові команди в bash, наприклад, для циклів або програм, що вимагають тут операторів, і дає цікавий спосіб зберегти трохи історії командного рядка, щоб подати файл для подальшого використання.

Отже, щоб відповісти на початкове запитання, ви також можете написати,

$ This is an example

а потім натисніть Ctrl+ x+, eщоб завантажити його vim. Також ви могли б мати,

 $ $(cat /etc/hosts)

і зробіть Meta(Alt/Opt/Esc)+ Ctrl+, eпотім Ctrl+ x+ e, що дозволить розмістити всі файли хостів в одному рядку і завантажити його vim(можливо, не найкраще використовувати ці функції, однак корисність цих методів може бути екстраполірована з кількох обговорених прикладів тут).

Зауважте, що я припускаю, що ваш режим readlineвстановлений у emacsрежим. Якщо ваш режим readlineвстановлено в vimрежимі, ви можете легко знайти відповідні прив’язки за допомогою команди:

bind -p

і пошук edit-and-execute-commandабо shell-expand-line, які відповідно були пов'язані з зв'язками Ctrl+ x+ eі Meta(Alt/Opt/Esc)+ Ctrl+ e.


Ви можете сказати bash використовувати замість vi клавіші замість emacs. Використовуйте, set -o viщоб увімкнути його. Тоді ви можете просто використовувати vвідображення у звичайному режимі для редагування поточної команди у вашому редакторі.
Quincy Bowers

1
Напевно, це чудовий трюк для редагування командного рядка за допомогою vi, але існують принаймні дві проблеми з використанням цього методу для читання тексту з stdin: 1. shell-expand-lineвидаліть нові рядки з розгорнутого тексту та 2. edit-and-execute-commandспробуйте виконати команду, написану в буфері , що б не було збережено чи ні, коли ви вийдете з vi.
toro2k

Вау, це приголомшливо. Я щодня дізнаюся нове про те, як читати, - здається,
Doorknob

2

У bash мені було корисно використовувати підстановку процесу за допомогою <(command)синтаксису, наприклад:

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

Дивись також:


4
Зверніть увагу, це працюватиме не у всіх оболонках. Я думаю , що це буде працювати тільки в bashі zsh(і не sh, ksh, dash, fish, csh, tcshі т.д.)
Мартін Tournoij

@Carpetsmoker повинен працювати в ksh88 і вище, я думаю, але так, заміна процесу не є POSIX.
муру

4
І зверніть увагу, щоб не обманювати себе! Коли ви запускаєте Vim таким чином, він відкриває буфер для подібного файлу /proc/PID/fd/FD. Якщо ви напишете буфер і вийдете, Vim не скаржиться, але файл, до якого ви написали, буде видалений ОС. Використовуючи -як ім'я файлу, відкритий буфер не має жодного файлу, пов’язаного з ним, тому якщо ви намагаєтеся вийти без (доки ви не використовуєте команду bang або подібне), збереження Vim попередить вас.
toro2k

1
Це приємно, тому що це добре узагальнює vimdiff <(echo foo) <(echo bar).
wchargin

@ toro2k Для подальших дій це виглядає як використання :nextта :prevперечитування потоку і нічого не отримує. Варто також зазначити, що процеси не є паралельними один одному - наприклад, cat <(sleep 3; echo a) <(echo b)друкує по порядку - і в той час, як catперемежування пише і читає, vimчекає, щоб файл "закінчив читання", перш ніж відобразити всі, крім зовнішнього кадру.
Джон П

-1

Якщо використання конвеєра до нового Vim не є вимогою, ви можете використовувати здатність Vim втягувати висновки команд у поточний буфер, поєднану з буфером, не захищеним файлом (як із :newредагуванням неіснуючого файлу)

:read!cat /etc/hosts в командному режимі буде розміщений вихід у вашому поточному буфері нижче поточного положення курсору.

Крім того, що потрібно видаляти порожній перший рядок, який залишається, коли це робиться в порожньому буфері, це добре працює і особливо зручно, якщо Vim вже працює.


1
Як це відповідає на питання?
муру

Він бере висновок команди і ставить його в vim.
ewatt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.