ファイル名でファイルパスのリストを並べ替えるには?

ファイル名でファイルパスのリストを並べ替えるには?

files.txtというテキストファイルには、次のファイルのリストがあります。

./themes/seven/images/list-item-rtl.png
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./xmlrpc.php
./MAINTAINERS.txt
./update.php
./README.txt
./COPYRIGHT.txt
./web.config

ファイル名でのみソートしたい(最後のスラッシュ以降の最初の文字に基づいて)。したがって、上記の出力は次のようになります。

./COPYRIGHT.txt
./MAINTAINERS.txt
./README.txt
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./themes/seven/images/list-item-rtl.png
./update.php
./web.config
./xmlrpc.php

どうすればいいですか?

答え1

$ awk -F '/' '{ printf "%s/%s\n", $NF, $0 }' files.txt | sort | cut -d '/' -f 2-
./COPYRIGHT.txt
./MAINTAINERS.txt
./README.txt
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./themes/seven/images/list-item-rtl.png
./update.php
./web.config
./xmlrpc.php

これにより、行の前にファイル名のコピーが追加され、その後に/1文字が追加されます。ファイル名は、/最後に区切られたフィールドから取得されます。最後のフィールド$NFはにありますawk

コマンドの出力がawkソートされます。このソート/では、行の前に追加された-delimitedフィールドを使用します。cutその後、追加された区切りフィールドを削除するために使用されます/

このアプローチは、パス名にリテラル改行文字が含まれていない限り機能します。

/パス名が文字(ディレクトリのパス名)で終わっても問題が発生する可能性があります。これにより、ソート列に空の文字列が生成されます。

また見なさい:シュワルツ変換

答え2

GNU awk( gawk) を使用して配列巡回を指定します。

awk -F'/' 'BEGIN {PROCINFO["sorted_in"] = "@ind_str_asc"} 
           { a[$NF]=$0 }
           END { for ( i in a ) { print a[i] } }' files.txt

この場合、データは配列にロードされ、インデックスは最後に区切られたフィールド(ファイル名など)として定義され、要素は/ファイルの行です。次に、印刷ステップのインデックス値でソートされた配列を繰り返します。


基本ユーティリティのみ:

paste <(rev files.txt | cut -d'/' -f 1 | rev) files.txt  | sort | cut -f2

関連情報