【问题标题】:How do I sort alphanumeric strings in Bash如何在 Bash 中对字母数字字符串进行排序
【发布时间】:2019-03-21 11:22:34
【问题描述】:

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

输入

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

我能得到的最接近的是 sort -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 之前。

【问题讨论】:

标签: linux bash sorting unix


【解决方案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 个字符进行正常排序,以防第一个字符发生冲突。这解决了下划线点问题。最后,我们对余数进行反向排序。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      你可以这样做:

      $ 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-05
        相关资源
        最近更新 更多