2016-08-11 4 views
1

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

Я написал следующий сценарий:

#!/bin/bash 


function rec_search { 
for file in `ls $1`; do 
echo ${1}/${item} 
if[[ -d $item ]]; then 
rec ${1}/${item} 
fi 
done 
} 

rec $1 

скрипт получает в качестве аргумента файла и ищет для него рекурсивно. Я считаю это бедным решением. и есть несколько вопросов улучшения:

  1. как найти файлы, которые содержат пробелы в именах
  2. может я эффективно использовать pwd команду для распечатки абсолютный адрес (я пробовал так, но безуспешно)
  3. каждый разумное улучшение кода
+1

[Не используйте команду ls] (http://mywiki.wooledge.org/ParsingLs) – Biffen

+0

@Inian 'find' не встроенная команду в * любой * оболочке. – chepner

+0

@chepner: Договорились, что это должно быть 'GNU findutils' – Inian

ответ

3

Ваш сценарий в настоящее время не может работать:

  • Функция определяется как , но вы, кажется, ошибочно называют rec
  • Вы должны поставить пробел после «если» в if[[

Есть некоторые другие серьезные проблемы, связанные с ним тоже:

  • for file in `ls $1` идет вразрез с рекомендацией «никогда не разобрать вывод ls», не будет работать для путей с пробелами или другими пробельными символами
  • Вы должны отступом тела if и for, чтобы сделать его легче читать

Сценарий может быть исправлена ​​следующим образом:

rec() { 
    for path; do 
     echo "$path" 
     if [[ -d "$path" ]]; then 
      rec "$path"/* 
     fi 
    done 
} 

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

+0

спасибо за ваше время! Я сделал некоторые важные выводы! –

0

Если вы используете bash 4 или более поздней версии (что, вероятно, если вы не используете это под Mac OS X), вы можете использовать оператор **.

rec() { 
    shopt -s globstar 
    for file in "$1"/**/*; do 
    echo "$file" 
    done 
}