在bash中,如何对包含数字的string进行sorting?

我有一个脚本输出文件path(通过查找):

/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 /foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 

我如何在Bash中列出它们,以便它们按照最后的数字以升序排列,而不考虑版本(1.2,1.2.3或1.2.3.4)

Ps: something部分最终可以包含一个短划线。

期望的输出:

 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 /foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 

我用了一个临时的前哨angular色来界定这个数字,但在我的情况下有点复杂。

在最后提取数字,将其前置到所有行,按数字排序,最后删除该数字:

 sed -r 's/(.*)([^0-9])([0-9]+)$/\3\1\2\3/' file | sort -n | sed 's/^[0-9]*//' 

随着你的输入,这将返回:

 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 /foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 

我认为这是施瓦茨变换 。


按件:

 $ sed -r 's/(.*)([^0-9])([0-9]+)$/\3\1\2\3/' a 16/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 1/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 5/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 2/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 10/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 #^ #note the numbers here $ sed -r 's/(.*)([^0-9])([0-9]+)$/\3\1\2\3/' a | sort -n 1/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 2/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 5/foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 10/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 16/foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 # ^ # now it is ordered $ sed -r 's/(.*)([^0-9])([0-9]+)$/\3\1\2\3/' a | sort -n | sed 's/^[0-9]*//' /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 /foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 

你可以使用这个sed + sort + awk

 sed -E 's/.*[^0-9]([0-9]+)$/\1 &/' file | sort -n | awk '{print $2}' /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something1 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something2 /foo/bar/example/foo/bar/example/foo-bar-example/1.2-something5 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3.4-something10 /foo/bar/example/foo/bar/example/foo-bar-example/1.2.3-something16 

如果你能确保你的文件中永远不会有'#'字符,你可以尝试:

 sed -e 's/something/#/g' filename.txt | sort -t# -k2 -n | sed -e 's/#/something/g'