如何在Bash中对字母数字字符串进行排序

时间:2018-10-16 20:38:46

标签: linux bash sorting unix

我想根据文件名对文件列表进行排序。

输入

280900_b24.txt
280900_b23.txt
280900_b25.txt
280900_b28.txt
280900.txt
280900_b27.txt
280900_b22.txt
280900_b30.txt
280900_b29.txt
280902.txt
280902_b01.txt
280901_b08.txt
280901.txt
280900_b26.txt

预期产量

280902_b01.txt
280902.txt
280901_b08.txt
280901.txt
280900_b30.txt
280900_b29.txt
280900_b28.txt
280900_b27.txt
280900_b26.txt
280900_b25.txt
280900_b24.txt
280900_b23.txt
280900_b22.txt
280900.txt

我能得到的最接近的是-r

280902.txt
280902_b01.txt
280901.txt
280901_b08.txt
280900.txt
280900_b30.txt
280900_b29.txt
280900_b28.txt
280900_b27.txt
280900_b26.txt
280900_b25.txt
280900_b24.txt
280900_b23.txt
280900_b22.txt

但是我希望具有_b#的文件位于名称中没有_b#的文件之前。示例:我希望280902_b01.txt出现在280902.txt之前。

3 个答案:

答案 0 :(得分:1)

我无法测试,但我相信您可以做到

 sort -k1.1,1.6r -k1.8,1.8 -k1.9r

但是,这会给

带来问题
 280900.txt
 280900_b30.txt
 280900_s30.txt

所以这样做可能更好

 sort -k1.1,1.6r -k1.7,1.7 -k1.8r

后者更好,因为它会在前6个字符上进行反向排序,然后在第7个字符上进行常规排序(如果第一个字符发生冲突)。这解决了下划线点问题。最后,我们对其余部分进行反向排序。

答案 1 :(得分:0)

您似乎希望对第一个数字部分进行反向排序。和_进行相同的排序,然后对所有内容进行正向(非反向)排序。当我尝试使用您的数据时,这就是您说的想要的内容:

sort -k1.1,1.6r -k1.8,1.14 input.txt

这对1-6列进行反向排序,忽略第7列,对8到14列进行正向排序。

答案 2 :(得分:0)

您可以这样做:

$ echo "280900_b24.txt
280900_b23.txt
280900_b25.txt
280900_b28.txt
280900.txt
280900_b27.txt
280900_b22.txt
280900_b30.txt
280900_b29.txt
280902.txt
280902_b01.txt
280901_b08.txt
280901.txt
280900_b26.txt" | sort -t _ -k1r
280902_b01.txt
280902.txt
280901_b08.txt
280901.txt
280900_b30.txt
280900_b29.txt
280900_b28.txt
280900_b27.txt
280900_b26.txt
280900_b25.txt
280900_b24.txt
280900_b23.txt
280900_b22.txt
280900.txt

说明:

sort -t _ -k1rn
      ^                 split
        ^               on the underscore
           ^            sort on field 1 in reverse order
                        the r is applied to the rest of the fields as well
                        after the first
               ^        numeric for the first field, 'ascii' for the rest

仅显示-r适用于其余字段,请考虑:

$ echo {9..11}_{9..11}.txt | tr ' ' '\n' 
9_9.txt
9_10.txt
9_11.txt
10_9.txt
10_10.txt
10_11.txt
11_9.txt
11_10.txt
11_11.txt

如果您以相同的方式对其进行排序:

$ echo {9..11}_{9..11}.txt | tr ' ' '\n' | sort -t _ -k1rn
11_10.txt
11_11.txt
11_9.txt
10_10.txt
10_11.txt
10_9.txt
9_10.txt
9_11.txt
9_9.txt

其余字段视为asciibetical。如果要在其余字段上输入数字:

$ echo {9..11}_{9..11}.txt | tr ' ' '\n' | sort -t _ -k1rn -k2rn
11_11.txt
11_10.txt
11_9.txt
10_11.txt
10_10.txt
10_9.txt
9_11.txt
9_10.txt
9_9.txt