在bash中,如何对带有数字的字符串进行排序?


37

如果我在目录中有这些文件

cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf
cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf

如何在Bash中列出它们,以便它们基于字符串的数字部分以升序排列。因此,结果顺序为cwcch1.pdf, cwcch2.pdf, ..., cwcch9.pdf, cwcch10.pdf,等等。

我最终想要做的是将pdf与pdftk以下内容连接起来

pdftk `ls *.pdf | sort -n` cat output output.pdf

但这不起作用,因为我的排序是错误的。


感谢您提供的所有出色答案。与Unix一样,有很多不同的出色方法可以使这只猫皮肤化。
ngm

Answers:


7

尽管采取的方法略有不同,但类似的事情可能会满足您的要求:

pdftk $(for n in {1..18}; do echo cwcch$n.pdf; done) cat output output.pdf

啊哈,好方法!确实的确做了我所做的事情,谢谢。
ngm


30

对于此特定示例,您还可以执行以下操作:

ls *.pdf | sort -k2 -th -n

也就是说,使用“ h”作为第二个字段(第-th个),对第二个字段(-k2)进行数字排序(-n)。


拆分然后在一个字段上排序-这是一个很好的提示,我相信将来肯定会派上用场,谢谢。
ngm

6

您可以-v在GNU中使用该选项ls:文本中自然的(版本)数字排序。

ls -1v cwcch*

这不适用于BSD ls(例如在OS X上),因为该-v选项具有不同的含义。


这是最简单的解决方案,需要更多支持者!
davidparks21

2

直接在命令行中使用shell扩展。扩展应正确订购它们。如果我pdftk正确理解的命令行语法,这将满足您的要求:

# shell expansion with square brackets
pdftk cwcch[1-9].pdf cwcch1[0-9].pdf cat output output.pdf

# shell expansion with curly braces
pdftk cwcch{{1..9},{10..18}}.pdf cat output output.pdf

或者,您可以尝试其他方法。当我需要执行此类操作时,通常会尝试提前正确格式化数字。如果我迟到了,并且已经像您的示例一样对PDF进行了编号,那么我将使用它来重新编号:

# rename is rename.pl aka prename -- perl rename script
# this adds a leading zero to single-digit numbers
rename 's/(\d)/0$1/' cwcch[1-9].pdf

现在,标准ls排序将正常工作。


2
也许更简洁一些:pdftk cwcch{{1..9},{10..18}}.pdf ...
暂停,直到另行通知。

好的补充。是标准的Bourne shell扩展语法还是bash扩展?
奎克吉x德09年


0

Sort -g用于按升序对数字进行排序。

anthony@mtt3:~$ sort --help | egrep "\-g"
-g, --general-numeric-sort  compare according to general numerical value


以下一个衬纸使用PDF文件名遍历一个文件,仅使用egrep -o捕获数字,并使用sort -g对数字进行升序排序。然后,将这些数字输入sed并将其插入。然后使用uniq消除重复项的输出。


代替uniq,您还可以使用awk:

awk '!x[$0]++'

以上等同于uniq。


您正在寻找的是这种衬板:

for i in `cat tmp | egrep -o "[0-9]*" | sort -g`; do cat tmp | sed "s/\(^[a-z]*\)\([0-9]*\)\(\.pdf\)/\1$i\3/g" | uniq; done


tmp的内容:

anthony@mtt3:~$ cat tmp
cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf
cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf 

编辑:

命令输出:

anthony@mtt3:~$ for i in `cat tmp | egrep -o "[0-9]*" | sort -g`; do cat tmp | sed "s/\(^[a-z]*\)\([0-9]*\)\(\.pdf\)/\1$i\3/g" | uniq; done

cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf
cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf

请问对一个班轮工作tmp文件?有任何输出要粘贴到答案中吗?
Xen2050

是。我将输出包括在我的OP中的“编辑”部分下。
阿格瓦拉2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.