Быстрый способ открытия результатов поиска `find` или` locate`

Когда я запускаю find или locate , соответствующие файлы будут заполнять stdout, по одному файлу на строку. Следующий шаг часто заключается в том, что я хочу открыть один из этих файлов. Это было бы быстрее и эффективнее, если бы мне не пришлось набирать весь путь к файлу, но просто мог бы каким-то образом взаимодействовать с результатами поиска. Какой самый быстрый способ открыть файл, отображаемый в результатах поиска?

Решения, подобные приведенным в разделе «Открыть результат», найти «с помощью` vi` , « Как найти» несколько файлов и открыть их в vim? , и как я могу воздействовать на результаты команды «locate»? требуют ввода довольно длинной второй команды, которая не так быстро, как хотелось бы.

Вместо этого существует способ, например, автоматически назначить каждый файл из результата поиска на числовое имя переменной (s1 – sn), чтобы открыть первый результат, я просто наберу vi $s1 ? Или это лучшее решение этой проблемы для использования нечеткого искателя, такого как fzf или fasd ?

  • Перемещение последних файлов из одного каталога в другой
  • Другие вопросы о -path для поиска
  • Поиск файлов, имеющих подтвержденный дубликат в том же каталоге, рекурсивно
  • Сделать поисковый снимок после каталогов?
  • Применение функции bash для каждого файла в подпапке рекурсивно
  • Как отслеживать, какие файлы в настоящее время растут в каталоге
  • как выбрать файлы в каталоге с булевым оператором AND
  • rsync только файлы новее, чем заданная дата, с --delete
  • 5 Solutions collect form web for “Быстрый способ открытия результатов поиска `find` или` locate`”

    Я имел это в своем ~/.screenrc некоторое время:

     bind -c pasteline 1 eval copy 'stuff "-Y"' 'paste .' bind -c pasteline 2 eval copy 'stuff "2-Y"' 'paste .' bind -c pasteline 3 eval copy 'stuff "3-Y"' 'paste .' bind -c pasteline 4 eval copy 'stuff "4-Y"' 'paste .' bind -c pasteline 5 eval copy 'stuff "5-Y"' 'paste .' bind -c pasteline 6 eval copy 'stuff "6-Y"' 'paste .' bind -c pasteline 7 eval copy 'stuff "7-Y"' 'paste .' bind -c pasteline 8 eval copy 'stuff "8-Y"' 'paste .' bind -c pasteline 9 eval copy 'stuff "9-Y"' 'paste .' bindkey ¬ command -c pasteline 

    В принципе, набрав ¬ 1 изнутри экрана, вставляет первую строку над курсором, ¬2 вторую строку и так далее.

    В моих ~/.Xdefaults меня также есть:

     XTerm.VT100.translations: #override\ Meta <KeyPress> /: dabbrev-expand() 

    Который позволяет xterm завершить (после Alt + / ) на том, что находится на экране (оглядываясь назад из положения курсора).

    С помощью zsh , когда вы используете screen , вы можете:

     copy-screen() { screen -X eval copy 'stuff "-$ H\r"' 'writebuf .lastoutput' killring=(${(Oaf)"$(<~/.lastoutput)"}) CUTBUFFER=$killring[1] killring[1]=() } zle -N copy-screen bindkey '\ec' copy-screen 

    для привязки Alt + C к этому виджету, который хранит строки над курсором в буфере вырезания и в кольце уничтожения (то, что вы вставляете с помощью Ctrl + Y и выполняете цикл с помощью Alt + Y в режиме emacs ). (вышеупомянутое предполагает, что screen был запущен из вашего домашнего каталога).

    Если вставленный текст нужно указывать (потому что он содержит пробелы или другие специальные символы оболочки, например), вы можете ввести Alt + " для zsh чтобы процитировать его.

    Например, вы только что запустили:

     $ find /usr/local -size +1M /usr/local/lib/liblzma.a /usr/local/share/doc/sudo/ChangeLog /usr/local/share/perl/5.18.2/Unicode/Unihan/Definition.db /usr/local/share/perl/5.18.2/Unicode/Unihan/RSKangXi.db /usr/local/share/perl/5.18.2/Unicode/Unihan/IRG_TSource.db /usr/local/share/perl/5.18.2/Unicode/Unihan/HanYu.db /usr/local/share/perl/5.18.2/Unicode/Unihan/RSUnicode.db /usr/local/share/perl/5.18.2/Unicode/Unihan/IRG_GSource.db /usr/local/share/perl/5.18.2/Unicode/Unihan/IRGKangXi.db /usr/local/share/perl/5.18.2/Unicode/Unihan/IRGHanyuDaZidian.db 

    И вы хотите открыть vim на этом sudo ChangeLog выше. При первом подходе вы должны ввести:

     vim ¬9 

    При втором подходе:

      vim / us Alt + / 

    И повторите, что Alt + / пока не попадете в журнал изменений.

    С третьим подходом:

      vim Alt + C Ctrl + Y Alt + Y 

    И повторите, что Alt + Y, пока не попадете в журнал изменений.

    Последний подход можно использовать для вашего запроса $s1 .

    Вместо сохранения в массиве killring , храните в массиве (например, $s ) и используйте $s[1] для первой строки, $s[2] для второго …

     copy-screen() { screen -X eval copy 'stuff "-$ H\r"' 'writebuf .lastoutput' s=(${(Oaf)"$(<~/.lastoutput)"}) } zle -N copy-screen bindkey '\ec' copy-screen 

    Что Alt + C хранит строки над курсором в массиве s .

    В любом случае то, что мы получаем, это то, что отображается на экране, что не обязательно совпадает с тем, что выводилось последним. Например, printf 'a\bc \n' выводит 5 байтов a , BS, c , SPC и LF, но отображает только c .

    Если вы можете перенести с уродством массивов Bash, вы можете сделать что-то вроде

     mapfile res < <(find -name <pattern>) 

    или

     mapfile res < <(locate <pattern>) 

    Это сохранит ваши строки в массиве res .

    Затем вы можете увидеть совпадения и повторить их:

     $ echo "${res[@]}" # lists all matches $ editor ${res[2]} # opens the third match 

    PS

    Я просто использую мышь, чтобы выбрать нужную мне линию. Или просто сделай

     $ editor `locate <pattern>` 

    если я знаю, что не так много результатов или «причудливых» персонажей.

    С bash :

     IFS=$'\n' select fname in $(locate fubar); do if [ "$fname" ]; then vim "$fname" break fi done 

    С Vim:

     !!locate fubar 

    – затем перейдите в нужный файл и нажмите g f . См. Также :h gf и :h 'isfname' .

    Еще один способ с Vim: см . :h :find . В последних версиях Vim см . :h :filter .

    Еще один способ с Vim: использовать плагин Unite . Или, для grep подобных операций, используйте плагин CtrlSF . Есть, конечно, много других способов.

    На ум приходит один метод. Вы можете использовать полноэкранный редактор, указанный в редакторе «РЕДАКЦИЯ» в среде оболочки. Редактор запускается нажатием кнопки ^X^E (ctrl-x, ctrl-e). В редакторе (например, vim) вы можете запустить:

     :r!find / 

    Результаты этого будут импортированы, после чего вы можете обрезать вывод по своему желанию, когда вы будете писать и выходить, содержимое будет запускаться как команда, как если бы вы ввели его в командной строке.

    Я объединил идеи Sato Katsura's и Stéphane Chazelas в сценарии, который сглажен для sr (для «Select Result»). Он может вызываться после команды, которая выводит пути по строкам в stdout. Например

     $ locate genomics /home/user/articles/macaulay_voet_2014_plos_genetics.pdf /home/user/articles/shmulevich_et_al_2003_comparative_functional_genomics.pdf $ sr zh 1) /home/user/articles/macaulay_voet_2014_plos_genetics.pdf 2) /home/user/articles/shmulevich_et_al_2003_comparative_functional_genomics.pdf #? 

    Затем скрипт ждет, когда я наберу номер и нажимаю enter, после чего он откроет этот пункт в программе, указанной в качестве первого аргумента (в данном случае zathura, для которого я определил стенографию zh в скрипте). Мне еще предстоит испытать это широко, но он делает все, что я хочу в данный момент.

    Моему текущему решению требуется tmux , так как он может получить доступ к выходу последней команды, не перезагружая его (путем копирования с терминала). Подобные решения существуют для screen как показано в ответе Стефана Хазеласа. Если вы не используете ни один из них, можно просто получить последнюю команду из истории, а затем снова оценить ее в инструкции select . Ниже приведен полный сценарий.

     #!/usr/bin/env bash # Enumerate stdout from the previous search command line by line. # Enable opening a file by passing the desired opening program as an # argument and then select a number from the output. # Defaults to using `xdg-open` when no argument is passed. # Does only work for stdout that list the full path to a file or relative # the directory this script is being called from. # Aliases are not expanded within bash scripts. # Create a few aliases instead of importing entire alias file. case $1 in '' ) opener='xdg-open' ;; 'vi' ) opener='nvim' ;; 'zh' ) opener='zathura' ;; * ) opener=$1 esac # The default split delimiter in bash is any whitespace. Change this # to only split on newline in order to account for filenames with spaces. old_IFS="$IFS" IFS=$'\n' # Use tmux to copy the paragraph above. This specific navigation sequence # only works if each prompt is prefaced with a newline, such as from having # `precmd() { print "" }` in `.zshrc` tmux copy-mode tmux send-keys 2 { 3 j 0 space } enter # Results are saved in an array for clarity search_results+=$(tmux save-buffer -) select fname in $search_results; do $opener "$fname" break done # Set IFS back to default IFS="$old_IFS" 
    Linux и Unix - лучшая ОС в мире.