【问题标题】:How can I sort file names by version numbers?如何按版本号对文件名进行排序?
【发布时间】:2011-05-01 18:29:39
【问题描述】:

在“数据”目录中有这些文件:

command-1.9a-setup
command-2.0a-setup
command-2.0c-setup
命令 2.0 设置

我想对文件进行排序以获得这个结果:

command-1.9a-setup
command-2.0-setup
command-2.0a-setup
command-2.0c-setup

我试过了

find /data/ -name 'command-*-setup' | sort --version-sort --field-separator=- -k2 

但输出是

command-1.9a-setup
command-2.0a-setup
command-2.0c-setup
命令 2.0 设置

我发现给我想要的输出的唯一方法是

tree -v /data

如何按所需顺序对输出进行排序?

【问题讨论】:

标签: bash sorting shell version


【解决方案1】:

如果您指定排序只考虑第二个字段 (-k2),请不要抱怨它不考虑第三个字段。

在你的情况下,运行 sort --version-sort 没有任何其他参数,也许这会更适合。

【讨论】:

  • 这不是第三个字段(在每种情况下都是“设置”)。
  • 对不起,它第三个字段,但事实上它是包含而不是排除。您必须使用-k2,2 告诉sort 密钥在字段2 开始并停止,以使OP 的命令起作用。
  • sort --version-sort 给了我这个打印订单:command-1.9a-setup command-2.0a-setup command-2.0c-setup command-2.0-setup
【解决方案2】:

看起来这样可行:

find /data/ -name 'command-*-setup' | sort -t - -V -k 2,2

不使用排序,但它有效:

tree -ivL 1 /data/ | perl -nlE 'say if /\Acommand-[0-9][0-9a-z.]*-setup\z/'

-v:按版本排序输出
-i:使树不打印缩进线
-L level:目录树的最大显示深度

【讨论】:

  • @DennisWilliamson:现在它也应该与command-10.1-setup 一起使用。
  • 这也会因非 GNU 排序而失败(即在 OS X 或 FreeBSD 中)。这是 GNU 解决方案,而不是 bash 解决方案。
【解决方案3】:

编辑: 事实证明,Benoit 走在了正确的轨道上,而 Roland 打破了平衡

您只需告诉sort只考虑字段 2(添加“,2”):

find ... | sort --version-sort --field-separator=- --key=2,2

原答案: 忽略

如果您的文件名中没有包含连字符之间的空格,您可以试试这个:

find ... | sed 's/.*-\([^-]*\)-.*/\1 \0/;s/[^0-9] /.&/' | sort --version-sort --field-separator=- --key=2 | sed 's/[^ ]* //'

第一个sed 命令使这些行看起来像这样(我添加了“10”以表明排序是数字):

1.9.a command-1.9a-setup
2.0.c command-2.0c-setup
2.0.a command-2.0a-setup
2.0 command-2.0-setup
10 command-10-setup

额外的点使字母后缀的版本号排在不带后缀的版本号之后。第二个sed 命令从每一行中删除前缀版本号。

失败的方式有很多。

【讨论】:

  • 当我只尝试这部分时,我得到了正确的顺序:find /home/mm/ztest/ -name 'truecrypt--setup' | sed 's/.-([^-]*)-.*/\1 \0/;s/[^0-9] /.&/' 但是整行不行;
  • @sid_com:command-10-setup 哪个失败?他们都为我工作。你的locale 是什么?你有什么版本的sort
  • 使用此排序设置,command-10-setup 位于第一个输出行中。语言环境:de_DE.UTF-8。排序(GNU coreutils)7.1
  • @sid_com:当我设置 LC_COLLATE=de_DE.utf8 并使用 GNU coreutils 7.4 进行排序时,command-10-setup 是最后一行(使用 sort --version-sort --field-separator=- --key=2,2)。
  • 第一行给了我想要的结果。第二行(带 sed)给了我与 sort --version-sort 相同的结果。
【解决方案4】:
$ cat files
command-1.9a-setup
command-2.0c-setup
command-10.1-setup
command-2.0a-setup
command-2.0-setup

$ cat files | sort -t- -k2,2 -n
command-1.9a-setup
command-2.0-setup
command-2.0a-setup
command-2.0c-setup
command-10.1-setup

$ tac files | sort -t- -k2,2 -n
command-1.9a-setup
command-2.0-setup
command-2.0a-setup
command-2.0c-setup
command-10.1-setup

【讨论】:

  • 我没有得到与你的排序选项相同的排序。
  • 您使用的是什么语言环境?我也没有收到这个订单。
  • 我使用的是CYGWIN_NT-5.1 bacc 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin,没有特殊的语言环境,所以应该和语言环境C一样。
【解决方案5】:

旧帖子,但是...ls -l --sort=version 可能会有所帮助(尽管对于 OP 的示例,排序与 ls -l 在 RHEL 7.2 中所做的相同):

command-1.9a-setup
command-2.0a-setup
command-2.0c-setup
command-2.0-setup

我猜是YMMV。

【讨论】:

    【解决方案6】:

    另一种方法是填充数字。

    此示例将所有数字填充为 8 位数字。 然后,它进行简单的字母数字排序。 然后,它会移除焊盘。

    $ pad() { perl -pe 's/(\d+)/0000000\1/g' | perl -pe 's/0*(\d{8})/\1/g'; }
    $ unpad() { perl -pe 's/0*([1-9]\d*|0)/\1/g'; }
    $ cat files | pad | sort | unpad
    command-1.9a-setup
    command-2.0-setup
    command-2.0a-setup
    command-2.0c-setup
    command-10.1-setup
    

    为了深入了解它的工作原理,让我们看一下填充后的排序结果:

    $ cat files | pad | sort
    command-00000001.00000009a-setup
    command-00000002.00000000-setup
    command-00000002.00000000a-setup
    command-00000002.00000000c-setup
    command-00000010.00000001-setup
    

    您会看到所有数字都很好地填充为 8 位数字,字母数字排序将文件名按所需的顺序排列。

    【讨论】:

      【解决方案7】:

      我的文件夹中有文件,需要根据编号按排序顺序获取这些名称。例如。 -

      abc_dr-1.txt
      hg_io-5.txt
      kls_er_we-3.txt
      sd-4.txt
      sl_rt_we_yh-2.txt
      

      我需要根据数字对它们进行排序。 所以我用这个来排序。

      ls -1 | sort -t '-' -nk2
      

      它给了我按数字排序的文件。

      【讨论】:

        猜你喜欢
        • 2013-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-29
        • 2016-11-11
        • 2016-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多