単一のコマンドでサブディレクトリでファイルを検索し、ファイル名でソートする方法は?

単一のコマンドでサブディレクトリでファイルを検索し、ファイル名でソートする方法は?

一般的なルックアップを使用した結果find . ! -path "./build*" -name "*.txt":

./tool/001-sub.txt
./tool/000-main.txt
./zo/001-int.txt
./zo/id/002-and.txt
./as/002-mod.txt

並べ替えるときsort -n

./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt

ただし、希望の出力は次のとおりです。

./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt

これは、出力が次に基づいていることを意味します。ファイル名のみただし、フォルダ情報は出力の一部として保持する必要があります。

編集する: サブディレクトリ構造に複数のレベルを含めることができるため、例はより複雑になります。

ベストアンサー1

最後のフィールド(フィールド区切り文字と見なされる)に基づいてソートする必要があります/。残念ながら、フィールド数が変更された場合(sort -k負の値しか取れない場合)、これを行うことができるツールは思い出されません。

この問題を解決するには、装飾 - 並べ替え - 装飾キャンセルを実行する必要があります。つまり、ファイル名を取得して先頭に配置し、フィールド区切り記号を付けてソートし、最初の列とフィールド区切り文字を削除します。

find . ! -path "./build*" -name "*.txt" |\
    awk -vFS=/ -vOFS=/ '{ print $NF,$0 }' |\
    sort -n -t / |\
    cut -f2- -d/

このawkコマンドは次のことを意味します。フィールド区切り記号 FSに設定されます/。これはフィールドの読み方に影響します。これ出力フィールド区切り記号 OFSまた/、;に設定すると、レコードの印刷方法に影響します。次のステートメントは、最後の列(NFレコードのフィールド数なので、最後のフィールドのインデックスでもある)とレコード全体(レコード全体$0)を印刷するように指示します。その間にOFSを追加してください。その後、リストがsort編集され、/フィールド区切り文字として扱われます。レコード内のファイル名が最初にあるので、それに応じてソートされます。次に、cutフィールド 2 を最後まで印刷し、/フィールド区切り記号として再度処理します。

おすすめ記事