2013-09-25 2 views
3

У меня есть дерево исходного кода, корень которого находится примерно в /home/me/workspace. Есть много подкаталогов на многих уровнях. В частности, существует путь, содержащий некоторые инструменты:Bash: поиск дерева каталогов

/home/me/workspace/tools/scripts 

Я пишу функцию оргии, которую я могу назвать из любого места в дереве, к которому я передаю строку tools/scripts. Функция должна переходить из текущего рабочего каталога в /, ища фрагмент пути tools/scripts, затем, если он найдет его, распечатайте абсолютный путь, в котором он найден. В этом примере будет напечатан /home/me/workspace. Если фрагмент пути вообще не найден, тогда ничего не печатается.

У меня уже есть следующая функция Баш, которая делает это для меня:

search_up() 
(
    while [ $PWD != "/" ]; do 
     if [ -e "$1" ]; then 
      pwd 
      break 
     fi 
     cd .. 
    done 
) 

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

Примечание: Я не ищет полный рекурсивный поиск всего дерева.

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

$ bash --version 
GNU bash, version 3.00.15(1)-release (x86_64-redhat-linux-gnu) 
Copyright (C) 2004 Free Software Foundation, Inc. 
$ 
+1

Вам нужно найти относительный путь к каталогу или абсолютный путь к каталогу? Абсолютный путь уже известен. Итак, вам нужен относительный путь от pwd. Это? – tuxnani

+0

Мне нужно найти абсолютный каталог, в котором существует фрагмент пути 'tools/scripts'. –

+0

Зачем вам нужно перемещаться по дереву? Почему бы просто не обратиться к ~/workspace/tools/scripts? –

ответ

1

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

#!/bin/bash 

search_up() { 
    local LOOK=${PWD%/} 
    while [[ -n $LOOK ]]; do 
     [[ -e $LOOK/$1 ]] && { 
      echo "$LOOK" 
      return 
     } 
     LOOK=${LOOK%/*} 
    done 
    [[ -e /$1 ]] && echo/
} 

search_up "$1" 

Пример:

bash script.sh /usr/local/bin 

Выход:

/ 
+0

+1 - Определенно лучше вообще не иметь дополнительной подоболочки, хотя я не ожидаю, что эта функция будет широко использоваться, чтобы действительно гарантировать такую ​​оптимизацию , –

1

Для записи, вот что я в конечном итоге с помощью:

while [ $PWD != "/" ]; do test -e tools/bin && { pwd; break; }; cd .. ; done 

Подобно моему О.П., но в конце концов мне удалось отбросить скобки в скобках() полностью, потому что эта строка сама вызывается с помощью команды «shell» из другой программы. Следовательно, также набирая все это на одну строку.

Мне все еще понравился разумный ответ KonsoleBox как возможно более общее решение, поэтому я принимаю это.

Смежные вопросы