Как "найти" несколько файлов и открыть их в vim?

10

Предположим, что у меня есть файл с именем, filename123.txtи это единственный файл, который назван так, и я могу сделать locateэто с помощью команды locate filename123. И он возвращает только этот файл.

Теперь я хочу открыть его с помощью vi/ vim. Но я не хочу идти в это место и вводить viкоманду с именем файла. Здесь я хочу, чтобы результат locate filename123был добавлен к команде vi. Как я могу это сделать? Я уже попробовал:

locate filename123 | vi

Но это не работает. И эта ошибка приходит в терминал:

santosh@santosh:~$ locate filename123 | vi
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: Finished.
Сантош Кумар
источник
возможный дубликат xargs и vi - «Ввод не из терминала»
kenorb

Ответы:

12

Вы можете использовать xargs:

locate filename123 | xargs vi

По умолчанию xargsбудет выполнено как можно меньше экземпляров указанной команды, передавая как можно больше параметров в соответствии с ARG_MAX системы . Чтобы ограничить количество параметров, передаваемых экземпляру vi, используйте опцию xargs' -n.

Для обработки имен файлов, содержащих пробелы, используйте xargs' -doption:

locate filename123 | xargs -d '\n' vi

Для обработки имен файлов, содержащих переводы строки, используйте параметр xargs' -0option ' вместе с параметром locate'' -0:

locate -0 filename123 | xargs -0 vi

(Если -0не доступно ни на одном из них, проверьте --nullтакже или другой способ указать символ в \000качестве разделителя.)

manatwork
источник
Можете ли вы сказать мне, что мешало мне открыть этот файл?
Сантош Кумар
1
@Santosh Вы передавали выходные данные команды в locateкачестве входных данных для vi. Vi, как и любая другая программа, ожидает, что имя файла (ов) будет работать в качестве аргументов.
Жиль "ТАК - перестань быть злым"
@manatwork Проблема в том, что я не могу найти и открыть имя файла с пробелами в нем. Например, эта команда откроет несколько файлов в vim: найдите I \ have \ to \ download | xargs vi
Сантош Кумар
3

Вы можете использовать расширение команды:

vi "$(locate filename123 | head -n1)"

Чтобы сделать vimчтение его стандартным вводом, вы можете сделать vim -, но это просто даст вам вывод, locateкоторые являются путями к имени файла. Это может сработать, хотя использование vim gfобычной команды откроет путь, на котором находится курсор.

редактировать

В случае имен файлов с пробелами в них лучше использовать xargsупомянутую опцию или vimрешение, описанное выше. Обратите внимание, чтобы сделать gfработу, вам нужно добавить место для isfname:

set isfname+=32

Этот совет и альтернативы описаны здесь .

Редактировать 2

Добавлены цитаты и headкак предложено PeterO в комментариях .

Тор
источник
Для файла с пробелами в них, когда я вставляю \ в имя файла, например, vi $ (найдите другой файл \). Vim открывает его как два отдельных файла anotherи file:(.
Сантош Кумар
Ваш ответ работает только тогда, когда у меня нет пробелов в файле, который я нахожу.
Сантош Кумар
Ответ обновлен.
Тор
2
@Thor: Для одного файла, как упоминалось в вопросе, вам просто нужно заключить в кавычки процесс-подстановку: vi "$(locate filename123)"... Чтобы убедиться, что он имеет только одно имя файла для работы:vi "$(locate filename123 |head -n1)"
Peter.O
PeterO: Ты прав, я тестировал только несколько хитов. Я добавил ваши комментарии к ответу.
Тор
1

Самый простой способ - передать в locateкачестве замены оболочки , например:

vim $(locate filename123)

Вы также можете использовать findвместо locateпередачи имен файлов для редактирования, например:

find . -name 'filename123' -exec vim {} +

В Unix / OSX вы можете использовать xargsс -oпараметром, например:

locate filename123 | xargs -o vim

-oОткройте команду stdin как / dev / tty в дочернем процессе перед выполнением команды. Это полезно, если вы хотите, чтобы xargs запускал интерактивное приложение.

Или в Linux попробуйте следующий обходной путь, используя:

locate filename123 | xargs -J% sh -c 'vim < /dev/tty $@'

Если вы используете разные команды, используйте подстановку команд для достижения этого, например:

vim $(locate filename123)
vim `locate filename123`

В качестве альтернативы используйте GNU parallelвместо xargsпринудительного распределения tty, например:

locate filename123 | parallel -X --tty vi

Примечание: parallelв Unix / OSX не будет работать, так как он имеет разные параметры и не поддерживает tty.

Многие другие популярные команды также предоставляют псевдо-tty распределение (например, -tв ssh), поэтому обратитесь за помощью.

Другое предложение - использовать vipe(командный канал Vim) или использовать следующий простой скрипт:

#!/bin/sh
# usage: locate filename123 | vip
exec vim < /dev/tty "$@"

Связанные с:

kenorb
источник