Откройте файл, заданный результатом команды в vim

34

Я делаю следующее почти каждый день

  1. Запустить поиск ( find -name somefile.txt)
  2. Откройте результат в vim

Проблема в том, что я должен скопировать и вставить результат findв vimкоманду. Есть ли способ избежать этого? Я немного поэкспериментировал ( find -name somefile.txt | vim), но не нашел ничего, что работает.

заранее спасибо

smauel
источник

Ответы:

31

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

vim $(find -name somefile.txt)

или

find -name somefile.txt -exec vim {} \;
кендырь
источник
1
хорошо. Если это то, что нужно, то найдите -name somefile.txt | xargs vim
balki
3
Нет, это не работает должным образом и может даже испортить ваш терминал! Вы не можете передать по каналу xargs vim, потому что vim ожидает ввода от интерактивного терминала.
Dogbane
1
Анонимный пользователь отмечает, что это не удастся, если в имени файла есть пробелы
Майкл Мрозек
4
Другая альтернатива будет vim `find -name somefile.txt`. @StuartPowers В качестве альтернативы, вы можете использовать, vim `!-1`если вы уже использовали эту находку, была ваша предыдущая команда
Бернхард
1
@balki, чтобы использовать xargs в этом сценарии, вы должны использовать флаг -o, он находится в man: -o Повторно открыть stdin как / dev / tty в дочернем процессе перед выполнением команды. Это полезно, если вы хотите, чтобы xargs запускал интерактивное приложение.
Давидм
7

Попробуй это:

  1. начать Vim
  2. в vim используйте следующее:

:r!find /<path> -name 'expression'

Результаты должны появиться в vim, когда поиск будет завершен.

Или

Пытаться:

find /<path> -name > results.txt
vim results.txt 
Карл
источник
Мое решение делает то же самое, но почему за него проголосовали?
балки
5

Если вы не против запустить команду еще раз: нажмите Upи добавьте xargsкоманду. Или используйте подстановку истории и запустите

!! | xargs vim          # won't work with file names containing \'" or whitespace
!! | xargs -d \\n vim   # GNU only (Linux, Cygwin)

Существует легкий способ сохранить выходные данные команды, которая работает в ksh и zsh, но не в bash (для этого требуется, чтобы выходная сторона конвейера выполнялась в родительской оболочке). Труба команда в функцию K(ЗШ определение ниже), в котором к ЭВЧ свой выходной сигнал в переменной $K.

function K {
    K=("${(@f)$(tee /dev/fd/3)}") 3>&1;
}
find  |K
vim $K

Автоматическое сохранение результатов каждой команды на самом деле невозможно только с помощью оболочки, вам нужно запустить команду в эмулируемом терминале. Вы можете сделать это, запустив внутри script(утилита BSD, но доступная в большинстве устройств, включая Linux и Solaris), которая сохраняет весь вывод вашего сеанса через файл (для надежного обнаружения последнего приглашения в машинописном тексте все еще требуются некоторые усилия) ).

Жиль "ТАК - перестань быть злым"
источник
2

Мне нравится использовать тики `(на той же клавише, что и ~)

> vim `find . -name somefile.txt`

Обратные тики выполняют команду внутри тиков, и затем команда может использовать выходные данные. Выше будут найдены все файлы somefile.txt, что позволит вам использовать их :nextдля перемещения по всем файлам.

Это очень полезно, если вы потратите пару попыток уточнить команду, потому что вы можете затем использовать подстановку истории, чтобы повторить команду для редактора.

> find . -name somefile.txt
./debug/somefile.txt
./somefile.txt
> vi `!!`
Мартин Йорк
источник
2

Должно быть, я здесь упустил, потому что я бы использовал:

:find **/somefile.txt

(если бы я знал, что был только один в моем :echo &path ) или, если бы я хотел их всех:

:args **/somefile.txt

Редактировать: Вау! Хорошо, так что я сделал промах точки - вы хотите найти список, а не сами файлы открыли? Попробуйте (опять же изнутри Vim):

!!find . -name somefile.txt

-- моя вина :)

Барри Артур
источник
1

Как отметил @davidmh в комментариях, вы можете использовать xargsс флагом, -oесли вы хотите использовать интерактивное приложение.

find . -name somefile.txt | xargs -o vim

Если вы не используете -o, вы, вероятно, испортите состояние терминала после выхода из vim. Если вы сделали это, вы сможете перезагрузить свой терминал с помощью следующей команды:

reset
дурум
источник
0

Я написал функцию, pvimкоторая делает то, что вы хотите. Если к pvimнему передаются несколько строк, игнорируются все, кроме первой, его можно расширить, хотя бы открыть несколько файлов в vim.

stu@sente ~ $ function pvim() { read -r somefile; exec < /dev/fd/1; vim "$somefile"; }
stu@sente ~ $ type pvim
pvim is a function
pvim ()
{
    read -r somefile;
    exec < /dev/fd/1;
    vi "$somefile"
}

Используйте это как:

stu@sente ~ $ find . -name "foo.txt" | pvim

который загрузит первый "foo.txt" в vim так же, как если бы вы набрали:

vim $(find . -name "foo.txt | head -n1")

сэнтэ
источник
0

Вот более простое xargsрешение, чем те, которые уже упоминались:

find -name somefile.txt | xargs vim -p

-pОпция указывает , vimчтобы открыть каждый файл в отдельной вкладке. Я считаю это более удобным, чем использование буферов.

Кори Кляйн
источник
0

Я обнаружил, что открытие файла с помощью locateinim очень удобно и намного быстрее, чем find.

Следующая команда ищет файл, вызванный app.pyпо пути, содержащему каталог MyPythonProject.

:args `locate '*MyPythonProject*app.py'`
Searene
источник