各ファイル名に同じ数の「-」区切り文字を含むファイルセットを並べ替えたい(数値の並べ替えには-nを使用)。
サンプルのリストは次のとおりです。
/home/flora/edvart/docs/schimmel-01.png
/home/flora/edvart/docs/schimmel-02.png
/home/flora/edvart/docs/schimmel-03.png
/home/flora/edvart/docs/schimmel-04.png
/home/flora/edvart/docs/schimmel-05.png
/home/flora/edvart/docs/schimmel-06.png
/home/flora/edvart/docs/schimmel-07.png
/home/flora/edvart/docs/schimmel-08.png
/home/flora/edvart/docs/schimmel-09.png
/home/flora/edvart/docs/schimmel-10.png
/home/flora/edvart/docs/schimmel-11.png
/home/flora/edvart/docs/schimmel-12.png
/home/flora/edvart/docs/schimmel-13.png
これは私が使用するコードです。
for fl in "$@"; do
fnme=${fl##*/}
ftyp=${fl##*.}
fdir=${fl%/*}
fnam=${fnme%.*}
nf=$( echo "$fnam" | awk -F '-' '{print NF}')
ifld=$(( nf + 1 ))
find "$fdir" -type f -name "${fnam}-*.png" |
awk -F'[-.]' '{print $(NF-1), $0}' RS='\0' ORS='\0' |
sort -znt '-' -k "$ifld"n |
while IFS= read -r flimg
do
echo "$flimg"
done
done
しかし、最初の3つのファイル-1、-2、-3を試してみると、結果はまだ数値順に並べ替えられません。
/home/flora/edvart/docs/schimmel-04.png
/home/flora/edvart/docs/schimmel-05.png
/home/flora/edvart/docs/schimmel-06.png
/home/flora/edvart/docs/schimmel-07.png
/home/flora/edvart/docs/schimmel-08.png
/home/flora/edvart/docs/schimmel-09.png
/home/flora/edvart/docs/schimmel-10.png
/home/flora/edvart/docs/schimmel-11.png
/home/flora/edvart/docs/schimmel-12.png
/home/flora/edvart/docs/schimmel-13.png
/home/flora/edvart/docs/schimmel-1.png
/home/flora/edvart/docs/schimmel-2.png
/home/flora/edvart/docs/schimmel-3.png
答え1
シェルzsh
には、シェルオプションと呼ばれるシェルオプションがありますNUMERIC_GLOB_SORT
。デフォルトでは、ワイルドカードパターンを数字で並べ替えます。
シェルでない場合zsh
:
zsh -o NUMERIC_GLOB_SORT -c 'printf "%s\n" /home/flora/edvart/docs/*.png'
または、(n)
glob修飾子を使用して特定のモードに対してのみこのシェルオプションを有効にします。
zsh -c 'printf "%s\n" /home/flora/edvart/docs/*.png(n)'
zsh -c
または、スクリプトからパターンをハードコーディングする代わりに、パターンをパラメータとして渡します。パターンには引用符が必要です。
zsh -c 'printf "%s\n" ${~1}(n)' zsh '/home/flora/edvart/docs/*.png'
テスト:
$ ls -d *.png
schimmel-04.png schimmel-08.png schimmel-11.png schimmel-3.png
schimmel-05.png schimmel-09.png schimmel-12.png
schimmel-06.png schimmel-1.png schimmel-13.png
schimmel-07.png schimmel-10.png schimmel-2.png
$ zsh -c 'printf "%s\n" ${~1}(n)' zsh '*.png'
schimmel-1.png
schimmel-2.png
schimmel-3.png
schimmel-04.png
schimmel-05.png
schimmel-06.png
schimmel-07.png
schimmel-08.png
schimmel-09.png
schimmel-10.png
schimmel-11.png
schimmel-12.png
schimmel-13.png
ディレクトリパスに数が多い場合は、ディレクトリパスの数が同じであれば動作し続けます。
答え2
sed
たぶん、最後のフィールドをキャプチャするためにファイルリストを操作する方が簡単です。そして最初に追加:
sed -e 's/^.*-\([^-]*\)\.[^.]*/\1-&/g'
これで、次のものを使用できます。最初cut
偽の「ファイル名」フィールドは、ソート後の最初のフィールドをスキップして追加のデータを削除できます。
cut -f2- -d-
だから:
ls | sed | sort | cut
はい
私はこの小さなディレクトリを作成し、その中に長さ0のファイルをいくつか触れました。
Oct 17 01:06 .
Oct 17 01:06 ..
Oct 17 01:06 201-ventosa-title-001.png
Oct 17 01:06 201-ventosa-title-002.png
Oct 17 01:06 201-ventosa-title-12.png
Oct 17 01:06 201-ventosa-title-17.png
Oct 17 01:06 201-ventosa-title-356.png
Oct 17 01:06 201-ventosa-title-91.png
Oct 17 01:06 333-ventosa-longer-title-this-time-77.jpg
ls | sed -e 's/^.*-\([^-]*\)\.[^.]*/\1-&/g' | sort -rn | cut -f2- -d-
予想通り、
201-ventosa-title-356.png
201-ventosa-title-91.png
333-ventosa-longer-title-this-time-77.jpg
201-ventosa-title-17.png
201-ventosa-title-12.png
201-ventosa-title-002.png
201-ventosa-title-001.png
(ソートから「r」オプションを削除すると、順序は逆になります)。
数値が別のフィールドにあっても、「77」要素は正しく配置されます。
答え3
mawk 1.3.3-17を使用しているため、問題が発生します。バージョン 1.3.4 以降では、「ヌル文字」を意味するレコード区切り文字として \0 を使用できます。以前のバージョンのmawk、BSD awk、Busybox awk、Plan 9 awkなどはすべて文字列を\0
空の文字列として扱います。つまり、「短絡モード」(二重改行区切りレコード)を有効にしますRS
。RS