If I have these files in a directory

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

how can I list them in Bash so that they are in ascending numeric order based on the number part of the string. So the resulting order is cwcch1.pdf, cwcch2.pdf, ..., cwcch9.pdf, cwcch10.pdf, etc.

What I'm ultimately trying to do is concatenate the pdfs with pdftk with something like the following

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

but that doesn't work as my sorting is wrong.

link|improve this question

Thanks for all the great answers to this. As always with Unix, there are many different excellent ways to skin this cat. – ngm Dec 6 '09 at 11:21
feedback

4 Answers

up vote 4 down vote accepted

Something like this might do what you want, though it takes a slightly different approach:

pdftk `for n in \`seq 18\`; do echo cwcch$n.pdf; done` cat output output.pdf
link|improve this answer
Aha, nice approach! It does indeed do what I what, thanks. – ngm Dec 6 '09 at 0:29
4  
You can avoid calling an extra external program like this: for n in {1..18) - or if you want to use seq anyway, you can avoid escaping backticks by doing this: $(for n in $(seq 18) ... ) since $() can be nested (in addition to other advantages: mywiki.wooledge.org/BashFAQ/082 ). – Dennis Williamson Dec 6 '09 at 6:47
feedback

For this particular example you could also do this:

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

That is, sort numerically (-n) on the second field (-k2) using 'h' as the field separator (-th).

link|improve this answer
Splitting and then sorting on one field -- that's a great tip that I'm sure will be handy in future, thanks. – ngm Dec 6 '09 at 11:30
feedback

Your sort may have the ability to do this for you:

sort --version-sort
link|improve this answer
feedback

Use shell expansion directly in a commandline. The expansion should order them properly. If I understand pdftk's commandline syntax properly, this will do what you want:

# 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

Or you can try a different approach. When I need to do something like this, I usually try to get my numbers formatted properly ahead of time. If I'm coming into it late and the PDFs are already numbered like your example, I'll use this to renumber:

# 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

Now the standard ls sorting will work properly.

link|improve this answer
2  
Perhaps a little more succinctly: pdftk cwcch{{1..9},{10..18}}.pdf ... – Dennis Williamson Dec 6 '09 at 7:02
good tip, added in. is that a standard Bourne shell expansion syntax or a bash extension? – quack quixote Dec 6 '09 at 7:43
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.