たとえば、最初に現在のディレクトリ内のファイルを出力し、次にサブディレクトリまたはサブディレクトリ内のファイルなどを常にその深さまで表示します。
5 に答える
find の "-printf" 機能を sort と組み合わせて使用します。自分で見て:
find . -printf "%d %p\n"|sort -n
深さでソートされたリストを生成します (最初の列に深さを表示し、2 番目の列にファイル パスを表示します)。これは私の現在のディレクトリに印刷されます:
0 .
1 ./bin
1 ./log
1 ./templates
2 ./bin/cc_env
3 ./files/test/mail.txt
最初の列を削除したい場合は、perl を使用できます。
find . -printf "%d %p\n"|sort -n|perl -pe 's/^\d+\s//;'
そして、あなたが行きます。perl フィルターは先頭の数字をすべて削除します。ディレクトリ自体を省略したい場合は、'-type f' パラメータを使用します。
find . -type f -printf "%d %p\n"|sort -n|perl -pe 's/^\d+\s//;'
ヒント: printf %d のようなトリックについては、find マンページを調べてください。
最も簡単な解決策:
$ echo * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*
a a/b a/b/c a/b/c/d1 a/b/c/d2 a/b/c/d1/e a/b/c/d2/e a/b/c/d1/e/f a/b/c/d2/e/f
または、列で:
$ echo * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/* |tr ' ' '\n'
a
a/b
a/b/c
a/b/c/d1
a/b/c/d2
a/b/c/d1/e
a/b/c/d2/e
a/b/c/d1/e/f
a/b/c/d2/e/f
ツリーの深さはこの例ではハードコーディングされていますが、小さなスクリプトを記述してより柔軟にすることができます。
A="*"
while true
do
B=$(echo $A)
[ "$B" = "$A" ] && break
echo $B
A="$A/*"
done | tr ' ' '\n'
使用例:
$ A="*"; while true; do B=$(echo $A); [ "$B" = "$A" ] && break; echo $B; A="$A/*"; done | tr ' ' '\n'
a
a/b
a/b/c
a/b/c/d1
a/b/c/d2
a/b/c/d1/e
a/b/c/d2/e
a/b/c/d1/e/f
a/b/c/d2/e/f
ツリーの例を次に示します。
$ mkdir -p a/b/c/d{1,2}/e/f
$ tree .
.
└── a
└── b
└── c
├── d1
│ └── e
│ └── f
└── d2
└── e
└── f
9 directories, 0 files
find
サブツリーを次々に表示するため、検索/深度ソリューションは明らかに機能しません。キーは、-depth
サブツリーを表示する必要がある方向を示します。しかし、もちろん、出力が深さでソートされるという意味ではありません。
$ find .
.
./a
./a/b
./a/b/c
./a/b/c/d2
./a/b/c/d2/e
./a/b/c/d2/e/f
./a/b/c/d1
./a/b/c/d1/e
./a/b/c/d1/e/f
$ find . -depth
./a/b/c/d2/e/f
./a/b/c/d2/e
./a/b/c/d2
./a/b/c/d1/e/f
./a/b/c/d1/e
./a/b/c/d1
./a/b/c
./a/b
./a
.
ご覧のとおり、どちらの場合も答えは正しくありません ( がある場合とない場合-find
)。
もっともらしい手法はfind
、ファイルのパス名を生成するために使用し、パス内のスラッシュの数が名前の前に来るようにファイル名を処理し、スラッシュの数 (深さ) で並べ替え、次に名前で並べ替えることができます。 . 簡単な解決策は、ファイル名に改行がないことを前提としています (他のスペースや奇妙なボール文字は関係ありません)。興味深い/トリッキーな部分は、特定の行のスラッシュの数を数えるクリーンな方法を見つけることです。
find . -type f -print |
perl -n -e '$x = $_; $x =~ tr%/%%cd; print length($x), " $_";' |
sort -k 1n -k 2 |
sed 's/^[0-9][0-9]* //'
その Perl を書くためのもっとコンパクトな方法があるかもしれませんが、それはうまくいきます。
関数を使用してファイルシステムを再帰的にトラバースします
test.sh:
#!/bin/bash
function traverse() {
find $1 -mindepth 1 -maxdepth 1 ! -type d -exec echo "$2"{} \;
for d in $(find $1 -mindepth 1 -maxdepth 1 -type d ! -name ".")
do
# if you just need files comment out next line
echo "$2$d"
traverse "$d" "${2} "
done
}
traverse $1
使用法:
./test.sh dir
出力を提供します:
./test.sh
./testA
./testA/dat2
./testA/dat1
./testA/testB
./testA/testB/dat4
./testC
./testC/dat3
find
次のコマンドを使用します。
find . -depth
からman find
:
-depth ディレクトリ自体の前に各ディレクトリの内容を処理します。