Linux: найти первый результат по указанному пути поиска

1271
Kevin A. Naudé

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

Я хочу найти в этом списке определенное имя файла. Тем не менее, я хочу только первый соответствующий путь.

Я рассмотрел следующие команды Linux:

  • which: работает только для двоичного файла и работает только с переменной $ PATH
  • whereis: работает с определенными типами файлов и работает только с переменной $ PATH
  • find: не поддерживает разделенные двоеточиями списки путей и возвращает несколько результатов

Вот несколько вещей, которые я пробовал:

  1. Я пытался использовать whereisпо следующей стратегии

    env WHEREIS="`which whereis`" PATH="$MY_PATH_LIST" $WHEREIS "$TARGET_FILE" 

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

  2. Я мог добраться whichдо работы

    env WHICH="`which which`" PATH="$MY_PATH_LIST" $WHICH "$MY_TARGET_FILE" 

    если была опция командной строки, чтобы заставить ее разрешать неисполняемые файлы.

  3. Затем я попытался решить проблему с find. Сначала я использовал регулярные выражения для расширения списка путей (я заменяю двоеточия пробелами). Затем я вызываю поиск, и он работает правильно. Тем не менее, он ищет все пути. Я не могу найти способ сказать ему, чтобы он прекратил поиск рано, если он найдет хороший результат.

    Я получил это на работу

     find $ -name "$MY_TARGET_FILE" | head -n 1 

    но это занимает много времени, чтобы завершить, потому что findвсе еще делает исчерпывающий поиск.

    Мне нужно, чтобы это выполнялось быстрее (выход при первом результате), потому что это будет выполняться много раз с другими параметрами.

У кого-нибудь есть лучшее решение, чтобы предложить?

Обратите внимание, что если все не удается, я могу написать решение не Bash. Напишите сейчас, я надеюсь на простое решение с использованием существующих инструментов.

5

2 ответа на вопрос

3
Daniel Beck

Вы можете просто использовать скрипт, который просто проверяет ( -e) наличие файла и останавливается, когда первый найден:

#!/bin/bash [[ $# -gt 0 ]] || { echo "Usage: $0 <filename> [pathspec]" >&2 ; exit 1 ; } if [[ $# -gt 1 ]] ; then P="$2" else P="$PATH" fi  IFS=: for DIR in $P ; do if [[ -e "$DIR/$1" ]] ; then echo "$DIR/$1" exit 0 fi done 

Пример:

$ ./search.sh  Usage: ./search.sh <filename> [pathspec]  $ ./search.sh ls /Users/danielbeck/bin/ls  $ ./search.sh pwd /bin/pwd  $ ./search.sh ls /bin /bin/ls  $ ./search.sh ls /usr/bin:/bin /bin/ls 
Спасибо, Даниэль. Это работает. Я удивлен, что для этого нет встроенной команды. Я собираюсь немного подождать, чтобы увидеть, есть ли какие-нибудь интересные комментарии. Пока что похоже, что этот пойдет к тебе. :-) Kevin A. Naudé 11 лет назад 0
0
dpatru

Use head to get the first result of the find command.

find `echo colon:separated:directories | sed 's/:/ /g'` -name filename | head -n1 

Or in a function:

$ function findin { find `echo $1 | sed 's/:/ /g'` -name $2 | head -n1; } $ findin this:that:other filename 

Похожие вопросы