如何按数字顺序和修改时间顺序对文件名进行排序?

如何按数字顺序和修改时间顺序对文件名进行排序?

我想通过pdfjoin/ pdfunite/...按照线程答案中讨论的数字顺序加入pdf文件linux命令合并pdf文件并进行数字排序修改的时间顺序。如果您在线程中使用解决方案,它会按数字顺序和字母顺序排列顺序。这对于文件名来说是有问题的,例如您看到两者具有相同的修改时间分钟精度,但Visceral精度较早(文件浏览器会注意到它并将其放在顺序Visceral中的第一位Modified)。

Filename               Modified
-----                  ---
3.THE ABC.pdf          10:39 
3.Visceral abc..pdf    10:39

完整的文件名

1.Description abc.pdf
2.Gabcd.pdf
3.THE ABC.pdf
3.Visceral abc..pdf
4.description of abc.pdf
5.Chraa..pdf

提案 #1 按数字和字母顺序工作,但不按数字和修改顺序工作

# https://stackoverflow.com/a/23643544/54964
ls -v *.pdf | ...
    bash -c 'IFS=$'"'"'\n'"'"' read -d "" -ra x;pdfunite "${x[@]}" output.pdf'

提案 #2 简化了大小写,但不处理文件名中的空格和其他特殊字符

# https://stackoverflow.com/a/23643544/54964
pdfunite $(ls *.pdf | sort -n) output.pdf

该命令的手册页中没有任何pdfunite --help有关顺序的内容,因此我认为应该通过ls/ sort/... 来完成该命令。sortmodified

测试 xhienne 的答案

您看到的输出中的顺序不正确2.jpg,并且4.jpg由于某种原因顺序错误

masi@masi:~/Documents$ ls -tr /home/masi/Documents/[0-9]* | sort -t. -k1,1n -s
/home/masi/Documents/1.jpg
/home/masi/Documents/3.jpg
/home/masi/Documents/5.jpg
/home/masi/Documents/6.jpg
/home/masi/Documents/7.jpg
/home/masi/Documents/8.jpg
/home/masi/Documents/9.jpg
/home/masi/Documents/10.jpg
/home/masi/Documents/2.jpg
/home/masi/Documents/4.jpg

第二次迭代

export LC_ALL=C; ls -tr /home/masi/Documents/[0-9]* | sort -t. -k1,1n -s

输出

/home/masi/Documents/1.jpg
/home/masi/Documents/3.jpg
/home/masi/Documents/5.jpg
/home/masi/Documents/6.jpg
/home/masi/Documents/7.jpg
/home/masi/Documents/8.jpg
/home/masi/Documents/9.jpg
/home/masi/Documents/10.jpg
/home/masi/Documents/2.jpg
/home/masi/Documents/4.jpg

操作系统:Debian 8.5

答案1

你可以这样做zsh

zmodload zsh/stat

prefixmtime () {
sortstring=${(l:6::0:)${REPLY%%.*}}$(zstat -F '%s' +mtime -- $REPLY)
REPLY=${sortstring}
}

print -rl -- *(o+prefixmtime)

print -rl如果您对结果满意,请替换为您的命令


它是如何工作的:
glob 将在这里排序(通过o+function)基于函数prefixmtime返回的内容,即通过连接左侧sortstring每个文件名的数字前缀获得的字符串 -${REPLY%%.*}带衬垫的带零(l:6::0:)(假设前缀最多 6 个字符长)mtime秒为单位(通过获得zstat模块)。如果运行以下命令,可能会更容易理解它的工作原理:

{ for f (*)
printf '%s %s\n' ${(l:6::0:)${f%%.*}}$(zstat -F '%s' +mtime -- $f) $f
} | sort -k1,1n

请注意,上面假设您与文件位于同一目录中,否则您必须在该函数中将排序字符串定义为

sortstring=${(l:6::0:)${${REPLY##*/}%%.*}}$(zstat -F '%s' +mtime -- $REPLY)

然后你可以使用目录路径,例如

print -rl some/place/else/*(o+prefixmtime)

答案2

find /home/masi/Documents -maxdepth 1 -type f -name '[0-9]*' -printf "%T+ %f\n" | sort -k2n -k1,1| cut -d ' ' -f 2- | xargs -i echo pdfunite /home/masi/Documents/{} output.pdf

这不会处理文件名中的新行。

-k1,1您可以通过更改来切换反转排序顺序-k1,1r,这将反转时间排序并-k2nr反转文件名排序。

答案3

解决方案是首先按修改时间排序,然后仅对第一个数字字段进行排序(假设这些字段以“.”分隔),同时禁用最后一个比较方法(又名稳定排序)。

ls -tr [0-9]* | sort -t. -k1,1n -s

[更新]

由于文件名中似乎有空格,因此必须使用来xargs执行pdfunite

ls -tr [0-9]* | ( sort -t. -k1,1n -s; echo output.pdf ) | xargs pdfunite

相关内容