В 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, есть много разных отличных способов снятия кожи с этой кошки.
НГМ
stackoverflow.com/questions/13088370/sort-numerically
Чиро Сантилли 新疆 改造 中心 996ICU 六四 事件

Ответы:

7

Нечто подобное может делать то, что вы хотите, хотя и немного другой подход:

pdftk $(for n in {1..18}; do echo cwcch$n.pdf; done) cat output output.pdf
retracile
источник
Ага, хороший подход! Это действительно делает то, что я, что, спасибо.
НГМ
60

Вы sortможете иметь возможность сделать это для вас:

sort --version-sort
Деннис Уильямсон
источник
Выдержка из соответствующей записи в -V, --version-sort natural sort of (version) numbers within text
справочной
Это то, что вам нужно. Но если ваша сортировка не предоставляет эту опцию, взгляните на этот пост: stackoverflow.com/a/4495368/1240018
eventhorizon
30

Для этого конкретного примера вы также можете сделать это:

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

То есть сортируйте численно (-n) по второму полю (-k2), используя 'h' в качестве разделителя полей (-th).

larsks
источник
Разделение, а затем сортировка по одному полю - это отличный совет, который, я уверен, пригодится в будущем, спасибо.
НГМ
6

Вы можете использовать -vопцию в GNU ls: натуральный вид (версии) чисел в тексте.

ls -1v cwcch*

Это не работает с BSD ls(например, в OS X), где -vопция имеет другое значение.

Ашутош Вишва Бандху
источник
Это самое простое решение, ему нужно больше людей, которые проголосуют против!
davidparks21
2

Используйте расширение оболочки прямо в командной строке. Расширение должно правильно их упорядочить. Если я правильно понимаю 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 или bashрасширение?
шарлатан-кихот
2

Вот метод, использующий сортировку:

ls | sort -k1.6n
п`одать
источник
0

Сортировка -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
Aguevara
источник
Делает это один вкладыш работы на tmpфайл? Любой вывод вставить в ответ?
Xen2050
Да. Я включил вывод в свой OP в разделе редактирования.
Агуэвара