Linuxで同じことをする方法は明らかにいくつかありますが、最近はfor i in xxx
ツリー内の各項目のリストを再帰的に参照する必要がありました。をtree
実行して(またはディレクトリ名のみを取得する)tree -fail
解決策を見つけましたtree -faild
が、次の質問がありました。ls
?
$ tree -fail
.
./.custom
./custom_loader.sh
./.git
./.git/branches
./.git/COMMIT_EDITMSG
./.git/config
./.git/description
./.git/HEAD
./.git/hooks
./.git/hooks/applypatch-msg.sample
答え1
シェルはbash
特別な**
グローブパターンを介してディレクトリに再帰できます。この**
パターンは同様のものと一致します*
が、/
パス名にまたがっています。
shopt -s globstar nullglob dotglob
for dirpath in ./**/; do
printf '%s\n' "$dirpath"
# whatever other code needs to be run on "$dirpath"
done
アクセス権があり、globstar
パターンが一致しない場合は、ループを完全にスキップして隠し**
ファイルnullglob
も表示できます。dotglob
このパターンは、./**/
現在のディレクトリのすべてのディレクトリと一致するように、現在のディレクトリの内側または下のすべてのディレクトリと一致します./*/
。
すべての種類のファイルを使用または一覧./**/*
表示します。./**
次のコマンドを使用して移植可能にこれを実行することもできますfind
。
find . -type d -exec sh -c '
for dirpath do
printf "%s\n" "$dirpath"
# whatever other code needs to be run on "$dirpath"
done' sh {} +
ここにスクリプトfind
のループへのsh -c
ディレクトリパス名を指定します。
これら2つの例を実行するときに見られる唯一の違いは、最初の例(ループを含む)がディレクトリへのbash
シンボリック**
リンクではfind
なく、ディレクトリへのシンボリックリンクをチェックすることです。
ディレクトリのみをリストしたい場合は、find
次のように例を大幅に短縮できます。
find . -type d -print
-type f
代わりに-type d
、通常のファイルのみを表示するには完全削除テストを使用し、-type
すべての種類のファイルを表示するには完全削除テストを使用してください。
明らかに、あなたはこのようなリストを得るために使用することができますが、ls
私はあなたのようにそのポイントを実際には知りません。ls
何もできませんが、出力を見る以外はできません。。
shopt -s globstar dotglob
ls -1d ./**
パターンが拡張されるパス名のリストが長すぎると、このコマンドは「引数リストが多すぎます」エラーを引き起こす危険性があります。この回答の他のコマンドにはこの問題はありません。
また、ls
ここでは実際に再帰は行われません。むしろ、シェルは再帰パターンを拡張し、./**
呼び出し前に引数リストを生成することもあります。ls
ls