我想对每个文件名中具有相同数量的“-”分隔符的一组文件进行排序(使用 -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
但是当我尝试使用前三个文件 -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
shellzsh
有一个名为 的 shell 选项NUMERIC_GLOB_SORT
。默认情况下,它使通配模式按数字排序。
来自非zsh
shell:
zsh -o NUMERIC_GLOB_SORT -c 'printf "%s\n" /home/flora/edvart/docs/*.png'
或者,使用(n)
glob 限定符仅针对给定模式启用此 shell 选项,
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
例子
我创建了这个小目录并触及了其中的一些零长度文件:
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