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

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

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

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

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" 
  • Найти рекурсивные каталоги и получить общее количество
  • Найти все папки, начиная с номера
  • Поиск и копирование каталогов, содержащих тип файла
  • Что означает знак вопроса в соответствующем шаблоне имени файла?
  • запрашивать все символические ссылки в каталоге
  • find (1): как применяется групповой символ звезды для отказа от некоторых имен файлов?
  • Добавить путь к имени файла
  • Как исключить каталоги NFS с помощью find?
  • Какую цель делает минус (-) в `find -! -exec` служить?
  • Разный вывод `find | xargs ls` для той же команды в разных версиях Ubuntu
  • Как найти и опорожнить некоторые каталоги
  • Interesting Posts

    Утечка памяти xorg

    Raid5, что может случиться? Разрушение раздела, теперь что мне делать?

    Где переменная окружения `$ TERM` установлена ​​в Debian Jessie для входа в консоль?

    Команда для обмена данными в HPUX itanium и HPUX PARISC?

    ssh -> screen -> ssh – как убить удаленный экранированный ssh, не убивая оригинальную сессию ssh

    Как отключить сенсорную панель во время ввода?

    Есть ли редактор XML-файлов для Linux с поддержкой grid view?

    строка 24: командная команда unterminated `s '

    Как воспроизвести результат поиска «mpc search»?

    Каков наилучший способ подсчета количества файлов в каталоге?

    numlock при запуске на linux mint 18.2

    Разве это имеет значение (например, по производительности), если я выполняю команду из сценария bash (по сравнению с командной строкой)?

    Реализация симметричной NAT с дополнительным портом источника? (программное обеспечение / ОС или аппаратный маршрутизатор)

    Настольная среда с мнемониками для Debian 8?

    Каковы преимущества GRUB над LILO?

    Linux и Unix - лучшая ОС в мире.