bash で find の結果を(ネストされたディレクトリを含む)アルファベット順に並べ替える方法 質問する

bash で find の結果を(ネストされたディレクトリを含む)アルファベット順に並べ替える方法 質問する

bash で「find」コマンドを実行した結果に基づくディレクトリのリストがあります。例として、find の結果は次のファイルです。

test/a/file
test/b/file
test/file
test/z/file

出力を次のように並べ替えます。

test/file
test/a/file
test/b/file
test/z/file

find コマンド内で結果を並べ替える方法、または結果を sort にパイプする方法はありますか?

ベストアンサー1

GNU バージョンの find をお持ちの場合は、これを試してください:

find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F '\0' '{print $3}'

これらのファイル名をループで使用するには、

find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F '\0' '{print $3}' | while read file; do
    # use $file
done

find コマンドは、各ファイルについて、(1) ディレクトリ、(2) ディレクトリ ツリーの深さ、(3) 完全な名前の 3 つを出力します。出力に深さを含めることで、 を使用して上記のsort -n並べ替えを行うことができます。最後に、並べ替えにのみ使用される最初の 2 つの列を削除するためにを使用します。test/filetest/a/fileawk

3 つのフィールド間の区切り文字として を使用すると\0、スペースとタブが含まれるファイル名を処理できます (ただし、残念ながら改行は処理できません)。

$ find test -type f
test/b/file
test/a/file
test/file
test/z/file
$ find test -type f -printf '%h\0%d\0%p\n' | sort -t '\0' -n | awk -F'\0' '{print $3}'
test/file
test/a/file
test/b/file
test/z/file

コマンドを変更できない場合はfind、次の複雑な置き換えを試してください。

find test -type f | while read file; do
    printf '%s\0%s\0%s\n' "${file%/*}" "$(tr -dc / <<< "$file")" "$file"
done | sort -t '\0' | awk -F'\0' '{print $3}'

これは同じことを行いますが、${file%/*}ファイルのディレクトリ名を取得するために使用され、trコマンドはファイルの「深さ」に相当するスラッシュの数をカウントするために使用されます。

(もっと簡単な答えがあることを願っています。あなたが尋ねていることはそれほど難しくないようです。しかし、簡単な解決策が思い浮かびません。)

おすすめ記事