在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.