特定のフォルダーのすべてのサブディレクトリでアクションを実行する必要があるスクリプトに取り組んでいます。
それを書く最も効率的な方法は何ですか?
for D in `find . -type d`
do
//Do whatever you need with D
done
サブプロセスの作成を回避するバージョン:
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
最も単純な非再帰的の方法は次のとおりです。
for d in */; do
echo "$d"
done
最後の/
は、ディレクトリのみを使用することを示しています。
必要はありません
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
便利なワンライナー
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
find . -type d -print0 | xargs -0 -n 1 my_command
これにより、サブシェルが作成されます(つまり、while
ループが終了すると変数値が失われます)。
find . -type d | while read -r dir
do
something
done
これはしません:
while read -r dir
do
something
done < <(find . -type d)
ディレクトリ名にスペースが含まれている場合は、どちらでも機能します。
あなたが試すことができます:
#!/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(現在のフォルダー.
を除く)のディレクトリのみを検索します
ディレクトリ名に空白が含まれている場合、受け入れられた回答は空白で途切れます。推奨される構文は、bash/kshの$()
です。 GNU find
などの-exec
+;
オプションを使用します。
find .... -exec mycommand +;
#this is same as passing to xargs
またはwhileループを使用します
find .... | while read -r D
do
...
done