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