如何对使用各种约定编号的文件名进行排序

时间:2018-08-23 03:10:10

标签: bash

这与我之前的问题类似,但我认为它与相似之处相比有更多不同。

我在Bash中有一个文件夹。在该文件夹中,是编号文件,所有文件类型均相同。这些文件的文件名不能包含空格。我需要按编号对这些文件进行排序。说,如果文件夹包含:

1.jpg
1.2.jpg
ch.002.jpg
Chapter3.jpg
Chapter_004:_Blah.jpg
Chapter_4.1.jpg
Chapter_5.jpg
Chapter_5.005.jpg

结果字符串为

"1.jpg 1.2.jpg 002.jpg Chapter3.jpg Chapter 004:_Blah.jpg Chapter_4.1.jpg Chapter_5.jpg Chapter_5.005.jpg"

如您所见,我需要浮点数,带前导零的数字和常规数字的支持。

2 个答案:

答案 0 :(得分:3)

带有粘贴,GNU排序和bash的Schwartzian transform

paste <(tr -cd '[0-9.\n]' < file | sort -V) file | awk '{print $2}' | tr '\n' ' '

输出:

1.jpg 1.2.jpg 002.jpg Chapter3.jpg Chapter_004:_Blah.jpg Chapter_4.1.jpg Chapter_5.jpg Chapter_5.005.jpg 

答案 1 :(得分:1)

由于您已声明这些文件的文件名不能包含空格。您可以使用一个相当简单的Bash管道,使用*和DSU(Decorate Sort Undecorate或Schwartzian转换)来生成DSU( gawk和数字排序。 (如果文件中可以包含空格,则方法相同,但是我们需要使用Bash循环而不是tr ' ' '\n'来分隔每个文件名。)

给出以下文件:

$ echo *
1.2.jpg 1.jpg Chapter3.jpg Chapter_004:_Blah.jpg Chapter_4.1.jpg Chapter_5.005.jpg Chapter_5.jpg ch.002.jpg

您可以这样做:

$ echo * | tr ' ' '\n' | gawk '{match($0, /([0-9]+\.{0,1}[0-9]*)/, arr); print arr[1] "/" $0}' | sort -n | awk -F"/" '{print $NF}' | tr '\n' ' '
1.jpg 1.2.jpg ch.002.jpg Chapter3.jpg Chapter_004:_Blah.jpg Chapter_4.1.jpg Chapter_5.jpg Chapter_5.005.jpg 

无论要添加到装饰部分的任何条件,都可以通过更改match($0, /([0-9]+\.{0,1}[0-9]*)/, arr)中的正则表达式来添加,以从文件名捕获该部分。

在Unix中,字符/是非法的文件名字符,因此在修饰和文件名之间是有效的分隔符。然后,我们根据装饰的float解释对数字进行排序,并使用第二个awk删除装饰。

如果您想向sort添加多个条件,则可以添加第一个awk并以无效的文件名字符作为分隔符的修饰。然后适当地使用sort的多字段参数,并用最后的awk命令取消修饰以打印文件名。