Як я можу редагувати всі файли, повернені знаходженням in vi в Linux?


27

Щось мені здається, що я багато роблю, це запустити команду find, а потім редагувати їх у vi, що виглядає приблизно так:

> find . "*.txt"
./file1.txt
./file2.txt
./path/to/file3.txt

> vi ./file1.txt ./file2.txt ./path/to/file3.txt

Чи є розумний і простий спосіб зробити це все в одному командному рядку?


1
Ви можете передати його у vi: find. "* .txt" | xargs vi
MaQleod

1
@MaQleod: Технічно це було б перенесенням на xargs .
grawity


Трубопровід xargsзнищив мій термінал оболонки. Правильне рішення - це наступне рішення від @DevSolar
typelogic

Відповіді:


41

Для цього слід зробити фокус:

find . -name "*.txt" -exec vim {} + 

Вживайте Vim, це краще для вашого здоров’я. :-)

Часто недоогляданий +варіант, щоб -execусі імена файлів (до меж довжини рядка) відображалися в одному рядку, тобто ви все одно отримуєте всі файли, відкриті за один vim сеанс (навігація :nдо наступного та :Nпопереднього файлу).

З vim -pвами ви отримуєте вкладку для кожного файлу. Перевірте :help tab-page-commandsбільш детальну інформацію.

З vim -oвами ви отримаєте горизонтально розділені вікна для кожного файлу, vim -Oвертикально розділені вікна. Перевірте :help window-move-cursorбільш детальну інформацію.

Зауважте, що попередня версія цієї відповіді, vim $(find . -name "*.txt")не працює з пробілами у іменах і має наслідки для безпеки.

Підключення xargs viнадає Warning: Input is not from a terminalплюс, а також термінал з цілком хибною поведінкою. Користь користувача пояснила, чому в коментарі нижче, і трохи більше пояснень у цьому питанні .


4
Не знаю, скільки ви знаєте про vim, але мені знадобилося / назавжди / зрозуміти, що: n показує наступний файл і: N показує попередній.
zpletan

4
@DevSolar: Vim очікує, що його stdin буде таким же, як і керуючий його термінал, і безпосередньо виконує різні пов'язані з терміналом йоктли на stdin. (Ви можете вважати це помилкою. Vim, безумовно, може відкрити /dev/ttyі викликати ioctl () на цьому; це просто лінь зробити це.) Коли виклик xargs, vim отримує /dev/nullяк його стандартний вхід, який просто ігнорує йоктли управління терміналом.
grawity

3
@zpletan: vim -pякщо ви хочете вкладки файлів. ( gtі gTперейдіть або клацніть мишкою.)
grawity

2
FYI, щоб уникнути попередження під час підключення vim, просто вкажіть -як перший аргумент, як у echo foobar | vim -.
Конрад Рудольф

2
@Konrad Rudolph: find . -name "*.txt" | vim -дає вам сеанс vim для безіменного файлу, який містить імена знайдених файлів, а це не те, про що просив ОП ...
DevSolar


1

Крім того, якщо ви хочете, щоб вони відкривались по одному, ви також можете використовувати find -exec або використовувати просту для циклу. Відредаговано за коментарем ceving.

find . -name "*.txt" -exec vi {} \;

або

OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for i in `find . -name "*.txt"`
    do
        vi $i
    done
IFS=$OLDIFS

... але чому б ви хотіли це робити?
DevSolar

@DevSolar Перший - вказати на здатність знаходити, другий - цикл загального призначення. Можливо, ви хочете зробити щось із кожного файлу, перш ніж редагувати його.
OldWolf

Ви коли-небудь пробували другу? По-перше: find повертає поточний каталог, оскільки -nameйого немає. І друге: команда збивається нещасно, як тільки ім'я файлу містить пробіл. -1 за необдуману відповідь.
завершення

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

@ceving Прийнятна точка. Я припускав, що оригінальні знахідки плакатів були дійсними для його потреб. Редагування.
OldWolf

0

Якщо ви вже ввели свою findкоманду, я вважаю, що це може бути набагато простіше використовувати xargsдля відкриття результатів пошуку:

find . -name "*.txt" | xargs vim -p

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


дякую, я підключив його, щоб знайти, щоб моя команда була: locate filename | xargs vim -p
talsibony

0

Для того, щоб змінити все *.txt, що ви можете просто запустити: vim *.txt. Щоб редагувати файли, повернені користувачем find, читайте далі.


У Unix / macOS можна використовувати findз BSD xargs(див. :) man xargs, Наприклад

find -L . -name "*.txt" -type f -print0 | xargs -o -0 vim

-o( xargs): Повторно відкрити stdin як / dev / tty в дочірньому процесі перед виконанням команди.

Пов’язані дані: Термінал приєднався після виклику Vim з xargs у Vim.SE.

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