34

Если у меня есть эти файлы в каталоге

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

но это не работает, так как моя сортировка не так.

7 ответов7

51

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

sort --version-sort
30

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

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

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

6

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

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

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

ls -1v cwcch*

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .