web-dev-qa-db-ja.com

Bashを使用してすべてのサブディレクトリでアクションを実行します

特定のフォルダーのすべてのサブディレクトリでアクションを実行する必要があるスクリプトに取り組んでいます。

それを書く最も効率的な方法は何ですか?

165
mikewilliamson
for D in `find . -type d`
do
    //Do whatever you need with D
done
159
Mike Clark

サブプロセスの作成を回避するバージョン:

for D in *; do
    if [ -d "${D}" ]; then
        echo "${D}"   # your processing here
    fi
done

または、アクションが単一のコマンドである場合、これはより簡潔です。

for D in *; do [ -d "${D}" ] && my_command; done

または、さらに簡潔なバージョン( thanks @enzotib )。このバージョンでは、Dの各値の末尾にスラッシュが付きます。

for D in */; do my_command; done
253
kanaka

最も単純な非再帰的の方法は次のとおりです。

for d in */; do
    echo "$d"
done

最後の/は、ディレクトリのみを使用することを示しています。

必要はありません

  • 見つける
  • awk
  • ...
85
d0x

findコマンドを使用します。

GNU findでは、-execdirパラメーターを使用できます。

find . -type d -execdir realpath "{}" ';'

または-execパラメーターを使用して:

find . -type d -exec sh -c 'cd -P "$0" && pwd -P' {} \;

またはxargsコマンドを使用:

find . -type d -print0 | xargs -0 -L1 sh -c 'cd "$0" && pwd && echo Do stuff'

またはforループを使用:

for d in */; { echo "$d"; }

再帰的にするには、代わりに拡張グロブ(**/)を試してください(有効にする:shopt -s extglob)。


その他の例については、以下を参照してください。 各ディレクトリに移動してコマンドを実行する方法 at SO

14
kenorb

便利なワンライナー

for D in *; do echo "$D"; done
for D in *; do find "$D" -type d; done ### Option A

find * -type d ### Option B

オプションAは、間にスペースがあるフォルダーに適しています。また、フォルダー名の各Wordを個別のエンティティとして印刷しないため、一般的に高速です。

# Option A
$ time for D in ./big_dir/*; do find "$D" -type d > /dev/null; done
real    0m0.327s
user    0m0.084s
sys     0m0.236s

# Option B
$ time for D in `find ./big_dir/* -type d`; do echo "$D" > /dev/null; done
real    0m0.787s
user    0m0.484s
sys     0m0.308s
12
Sriram Murali

find . -type d -print0 | xargs -0 -n 1 my_command

9
Paul Tomblin

これにより、サブシェルが作成されます(つまり、whileループが終了すると変数値が失われます)。

find . -type d | while read -r dir
do
    something
done

これはしません:

while read -r dir
do
    something
done < <(find . -type d)

ディレクトリ名にスペースが含まれている場合は、どちらでも機能します。

7

あなたが試すことができます:

#!/bin/bash
### $1 == the first args to this script
### usage: script.sh /path/to/dir/

for f in `find . -maxdepth 1 -mindepth 1 -type d`; do
  cd "$f"
  <your job here>
done

または類似...

説明:

find . -maxdepth 1 -mindepth 1 -type d:最大再帰深度1(サブディレクトリ$ 1のみ)および最小深度1(現在のフォルダー.を除く)のディレクトリのみを検索します

5
Henry Dobson

ディレクトリ名に空白が含まれている場合、受け入れられた回答は空白で途切れます。推奨される構文は、bash/kshの$()です。 GNU findなどの-exec+;オプションを使用します。

find .... -exec mycommand +;#this is same as passing to xargs

またはwhileループを使用します

find .... |  while read -r D
do
  ...
done 
4
ghostdog74