Я хочу, щоб мій скрипт оболонки відвідував усі підкаталоги в головному каталозі. Зробіть щось у каталогах, надішліть висновок у файл котушки та перейдіть до наступного каталогу. Розглянемо головний Dir = / tmp Sub Dir = ABCD (Чотири підкаталоги)
Я хочу, щоб мій скрипт оболонки відвідував усі підкаталоги в головному каталозі. Зробіть щось у каталогах, надішліть висновок у файл котушки та перейдіть до наступного каталогу. Розглянемо головний Dir = / tmp Sub Dir = ABCD (Чотири підкаталоги)
Відповіді:
Використовуйте for
цикл:
for d in $(find /path/to/dir -maxdepth 1 -type d)
do
#Do something, the directory is accessible with $d:
echo $d
done >output_file
Він шукає лише підкаталоги каталогу /path/to/dir
. Зауважте, що простий приклад вище не вдасться, якщо імена каталогів містять пробіли або спеціальні символи. Більш безпечний підхід:
find /tmp -maxdepth 1 -type d -print0 |
while IFS= read -rd '' dir; do echo "$dir"; done
Або на простоті bash
:
for d in /path/to/dir/*; do
if [ -d "$d" ]; then
echo "$d"
fi
done
(зауважте, що всупереч find
цьому також враховуються посилання на каталоги та виключаються приховані)
find
подібного.
date +"%m%d20%Y"
| xargs echo echo $ d
date +"%m%d20%Y"
| xargs echo echo $ d Очікуваний результат ls -ltr з усіх підкаталогів . Вище петля не працює
Я повний bash
новачок, але ветеран ООН * X. Хоча, безсумнівно, це можна зробити в сценаріях оболонок Баша, але в старі часи ми find [-maxdepth <levels>] <start-dir> -exec <command> ;
цього домагалися. Ви можете man find
пограти і пограти, можливо, поки хтось не скаже вам, як це зробити bash
!
find
команди.
$(find...)
в поганій практиці .
Схоже, ви хочете, щоб імена файлів у кожному з підкаталів; ls -l | awk
мало міцним, для того, що якщо ці імена файлів містять прогалини і / або нового рядка? Нижче find
буде працювати навіть для find
s, у яких цього не -maxdepth
відбувається:
find . ! -name . -type d -prune -exec sh -c '
cd "$1" && \
find "." ! -name . -prune -type f
' {} {} \;
Можливо також використання ls, grep та tr
for dir in $(ls -1FA | grep / | tr -d /); do echo $dir/something; done
ls -1FA | grep / | tr -d / | while IFS= read -r TD; do echo $TD/something; done
du / sed також може бути використаний як селектор, якщо вашому ls бракує наведених вище варіантів
du --max-depth=1 | sed -e 's/^.*\.\///' | grep -v '\.$'
Можливо, важливо зазначити, що ці приклади повертають приховані каталоги та виключають батьківські та поточні каталоги
ls
записує по одному файлу на рядок (що -1
вказує параметр) за замовчуванням, коли стандартним висновком є труба (тому це зайве у ваших відповідях). (2) Розбір результатів ls
- погана ідея - дивіться це і це . Ваша перша відповідь буде невдалою, якщо каталоги мають пробіли (або нові рядки) у своїх назвах, і всі будуть невдалими, якщо у своїх назвах є нові рядки. (3) Ви завжди повинні цитувати змінні оболонки (наприклад, "$dir"
), якщо у вас немає вагомих причин цього не робити, і ви впевнені, що знаєте, що робите.