bash 如何按版本号对文件名进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4041210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:50:07  来源:igfitidea点击:

How can I sort file names by version numbers?

bashsortingshellversion

提问by sid_com

In the directory "data" are these files:

在目录“data”中是这些文件:

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

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

I would like to sort the files to get this result:

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

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

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

I tried this

我试过这个

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

but the output was

但输出是

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

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

The only way I found that gave me my desired output was

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

tree -v /data

How could I get with sort the output in the wanted order?

我怎样才能按照想要的顺序对输出进行排序?

采纳答案by Paused until further notice.

Edit:It turns out that Benoit was sort of on the right track and Roland tipped the balance

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

You simply need to tell sortto consider onlyfield 2 (add ",2"):

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

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

Original Answer:ignore

原答案:无视

If none of your filenames contain spaces between the hyphens, you can try this:

如果您的文件名都没有在连字符之间包含空格,您可以尝试以下操作:

find ... | sed 's/.*-\([^-]*\)-.*/ 
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
/;s/[^0-9] /.&/' | sort --version-sort --field-separator=- --key=2 | sed 's/[^ ]* //'

The first sedcommand makes the lines look like this (I added "10" to show that the sort is numeric):

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

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

The extra dot makes the letter suffixed version number sort after the version number without the suffix. The second sedcommand removes the prefixed version number from each line.

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

There are lots of ways this can fail.

有很多方法可能会失败。

回答by Benoit

If you specify to sort that you only want to consider the second field (-k2) don't complain that it does not consider the third one.

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

In your case, run sort --version-sortwithout any other argument, maybe this will suit better.

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

回答by sid_com

Looks like this works:

看起来像这样:

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

not with sort but it works:

不是排序,但它有效:

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

-v: sort the output by version
-i: makes tree not print the indentation lines
-L level: max display depth of the directory tree

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

回答by vesperto

Old post, but... ls -l --sort=versionmay be of assistance (although for OP's example the sort is the same as done by ls -lin a RHEL 7.2):

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

$ pad() { perl -pe 's/(\d+)/0000000/g' | perl -pe 's/0*(\d{8})//g'; }
$ unpad() { perl -pe 's/0*([1-9]\d*|0)//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

YMMV i guess.

YMMV 我猜。

回答by Stephen Quan

Another way to do this is to pad your numbers.

另一种方法是填充您的数字。

This example pads all numbers to 8 digits. Then, it does a plain alphanumeric sort. Then, it removes the pad.

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

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

To get some insight into how this works, let's look at the padded sorted result:

为了深入了解这是如何工作的,让我们看一下填充后的排序结果:

$ 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

You'll see that with all the numbers nicely padded to 8 digits, the alphanumeric sort puts the filenames into their desired order.

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

回答by Roland Illig

##代码##