主な-depth
ものはfind
深さ優先検索を実行することです。
ただし、基本的な順序は次のとおりです。いいえ幅優先検索。
基本シーケンスは、「処理ノードの深さ優先巡回」として非公式に記述することができる。最初逆追跡中にそうする代わりに発生しました。 」
大雨優先探索が本当に必要です。どうすればfind
このような行動をすることができますか?
説明の便宜のために、以下の設定が使用される。
$ mkdir -p alpha/{bravo,charlie,delta}
$ touch alpha/charlie/{alpha,beta,gamma,phi}
find
次の基本的な動作があります。
$ find alpha
alpha
alpha/charlie
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
alpha/delta
alpha/bravo
そして、-depth
次のように実行されます。
$ find alpha -depth
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
alpha/charlie
alpha/delta
alpha/bravo
alpha
しかし、私が望むのは、次の(仮想)オプションです。
$ find alpha -bfs
alpha
alpha/charlie
alpha/delta
alpha/bravo
alpha/charlie/alpha
alpha/charlie/phi
alpha/charlie/beta
alpha/charlie/gamma
つまり、find
処理/報告する必要があります。みんな追加処理の前に、ファイル/ディレクトリを指定された深さに配置します。
どうすればいいですか?
答え1
# cat ./bfind
#!/bin/bash
i=0
while results=$(find "$@" -mindepth $i -maxdepth $i) && [[ -n $results ]]; do
echo "$results"
((i++))
done
これはfind
深さと反復を加えることによって達成される。結果は重複する可能性がありますが、簡単にフィルタリングできると思います。
答え2
シェルワイルドカードを使用すると、簡単にこれを行うことができます。ますます多くのディレクトリレベルでパターンを構築してください。
pattern='*'
set -- $pattern
while [ $# -ne 1 ] || [ "$1" != "$pattern" ]; do
for file; do
…
done
pattern="$pattern/*"
set -- $pattern
done
これによりポイントファイルが失われます。これを含めるには、FIGNORE='.?(.)'
ksh、bash、またはzshshopt -s dotglob
で使用してください。setopt glob_dots
指示:
- ファイルが多いとメモリが消費される可能性があります。
- これはディレクトリのシンボリックリンクを再帰的に巡回します。
ディレクトリとディレクトリ以外の順序を選択し、パフォーマンスが重要でない場合は、2つのパスを作成して[ -d "$file" ]
各パスでテストできます。
答え3
主にパス名の文字数find
に基づいて並べ替えるようにパイプできます。/
例えば、
find alpha |
awk '{n=gsub("/","/",$0);printf "%04d/%s\n",n,$0}' |
sort -t/ |
sed 's|[^/]*/||'
awk
これは、パス名の前にスラッシュ数を追加し、sed
末尾からこのプレフィックスを削除するために使用されます。
実際には、ディレクトリの内容をalpha/charlie+
後で一覧表示したい場合があるので、必要な深さをalpha/charlie
指定する必要があります。sort -t/ -k1,1 -k2,2 -k3,3 -k4,4
答え4
ファイルを探して速度ではなく順序に興味がある場合(たとえば、インタラクティブプロンプトに何千ものファイルを一覧表示する場合)、次の簡単なソリューションを使用できます。
find -depth -type f | tac