Перейдіть у всі підкаталоги та зробіть щось у скрипті оболонки Unix


17

Я хочу, щоб мій скрипт оболонки відвідував усі підкаталоги в головному каталозі. Зробіть щось у каталогах, надішліть висновок у файл котушки та перейдіть до наступного каталогу. Розглянемо головний Dir = / tmp Sub Dir = ABCD (Чотири підкаталоги)


2
Гаразд, покажіть нам поки що ваш сценарій. Яка частина цього доставляє вам клопоту?
terdon

Відповіді:


22

Використовуйте 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цьому також враховуються посилання на каталоги та виключаються приховані)


1
принаймні вказати на обмеження та ризики, пов'язані з обробкою результатів findподібного.
Стефан Шазелас

Привіт ... я намагався запустити цикл для d в $ (знайти / резервне копіювання / АШИЙ -maxdepth 1 -тип d) зробити ls -l | awk '{print $ 9}' | grep CC * _ date +"%m%d20%Y"| xargs echo echo $ d
Ашиш

Привіт ... Я спробував нижче для циклу. для d в $ (find / backup / ASHISH -maxdepth 1 -тип d) do ls -l | awk '{print $ 9}' | grep CC * _ date +"%m%d20%Y"| xargs echo echo $ d Очікуваний результат ls -ltr з усіх підкаталогів . Вище петля не працює
Ashish

1

Я повний bashновачок, але ветеран ООН * X. Хоча, безсумнівно, це можна зробити в сценаріях оболонок Баша, але в старі часи ми find [-maxdepth <levels>] <start-dir> -exec <command> ;цього домагалися. Ви можете man findпограти і пограти, можливо, поки хтось не скаже вам, як це зробити bash!


Я дуже поласканий тим, що моя відповідь на "контур" отримала підсумкове голосування. Однак чому відповідь @chaos нижче отримала перемогу? (Як новачок у цій дошці, я не можу публікувати цей коментар проти його відповіді, лише проти моєї власної.) Його друга пропозиція є правильною для рішення сценарію оболонки і уникає накладних витрат зовнішньої findкоманди.
JonBrave

Друга його справді правильна. Його перший вийде з ладу, якщо імена каталогів містять пробіли або спеціальні символи (наприклад, косої риски). Дивіться правку, яку я внесла до його відповіді щодо безпечної версії.
terdon

Я згоден. Це була його друга, лише оболонка, відповідь, яку я хвалив.
JonBrave

Я знаю, я просто пояснював голосування (яке я не кидав).
terdon


1

Схоже, ви хочете, щоб імена файлів у кожному з підкаталів; ls -l | awkмало міцним, для того, що якщо ці імена файлів містять прогалини і / або нового рядка? Нижче findбуде працювати навіть для finds, у яких цього не -maxdepthвідбувається:

find . ! -name . -type d -prune -exec sh -c '
   cd "$1" && \
   find "." ! -name . -prune  -type f
' {} {} \;

0

Я отримав рішення. Команда find нижче відповідає моїм вимогам.

find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && ls -l |awk '{ print $9 }' |grep `date +"%m%d%Y"`|xargs echo" \;

0

Можливо також використання 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 '\.$'

Можливо, важливо зазначити, що ці приклади повертають приховані каталоги та виключають батьківські та поточні каталоги


1
(1)  lsзаписує по одному файлу на рядок (що -1вказує параметр) за замовчуванням, коли стандартним висновком є ​​труба (тому це зайве у ваших відповідях). (2) Розбір результатів ls- погана ідея - дивіться це і це . Ваша перша відповідь буде невдалою, якщо каталоги мають пробіли (або нові рядки) у своїх назвах, і всі будуть невдалими, якщо у своїх назвах є нові рядки. (3) Ви завжди повинні цитувати змінні оболонки (наприклад, "$dir"), якщо у вас немає вагомих причин цього не робити, і ви впевнені, що знаєте, що робите.
Скотт

Хороші бали Скотта. Залишаючи відповідь так, як для багатьох систем без кричущо названих панів, я вважаю, що це може бути корисним для тих, хто виходить.
JGurtz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.