Как архивировать файлы с отсортированным порядком?

10

Если вы tarкаталог рекурсивно, он просто использует порядок из ОС readdir.

Но в некоторых случаях приятно отсортировать отсортированные файлы.

Что такое хороший способ отсортировать каталог по алфавиту?


Обратите внимание, что для целей этого вопроса, gnu-tar в типичной системе Linux подходит.

ideasman42
источник
Возможный дубликат ниже, проверьте ниже ссылки unix.stackexchange.com/questions/120143/… superuser.com/questions/172367/…
Jaymin Dabhi
Я видел это, но я не спрашиваю, как установлен порядок, вместо этого я хочу отсортировать их.
ideasman42
См. Также unix.stackexchange.com/a/67018 для сортировки дерева каталогов по имени.
Стефан Шазелас

Ответы:

17

Для GNU tar:

--sort=ORDER
 Specify the directory sorting order when reading directories.
 ORDER may be one of the following:

`none'
      No directory sorting is performed. This is the default.

`name'
      Sort the directory entries on name. The operating system may
      deliver directory entries in a more or less random order, and
      sorting them makes archive creation reproducible.

`inode'
      Sort the directory entries on inode number. Sorting
      directories on inode number may reduce the amount of disk
      seek operations when creating an archive for some file
      systems.

Вы, вероятно, также хотите посмотреть --preserve-order.

mikeserv
источник
8
--sortбыл представлен в версии tar 1.28. --preserve-orderне имеет отношения к этому вопросу.
Ммсмит
Я продолжаю иметь tar: Exiting with failure status due to previous errorsошибку. @mhsmith
Alper
3

С zshвместо:

pax -w dir

Использование:

pax -dw dir dir/**/*(D)

Вы можете сделать то же самое с последними версиями bash -O globstar -O dotglobс:

pax -dw dir/**

Или последние версии FIGNORE='@(.|..)' ksh93 -o globstarс:

pax -dw dir dir/**

paxэто стандартная команда для создания tarфайлов. Вывод идет в стандартный вывод. Шарики оболочки сортируются по имени.

Если вы столкнулись с слишком длинной ошибкой списка Arg , вы можете изменить на:

printf '%s\0' dir dir/**/*(D) | pax -0dw

(не все paxреализации поддерживают, -0хотя).

Стефан Шазелас
источник
2

tarСам не может этого сделать, поэтому вы должны создать его из правильно упорядоченного списка. В принципе, вы можете использовать параметр tar's' -T, но нет никакого способа указать, что имена файлов в этом списке должны заканчиваться NUL. Так что если у вас есть какие-либо имена файлов с символами новой строки в них (что разрешено), это просто сломается.

Лучшим вариантом является использование cpioдля генерации файлов, так как он принимает завершенный по NUL список имен файлов и может генерировать tar-файлы.

Если ваша tarкоманда будет:

tar cvf /somedir/all.tar .

Затем для того, чтобы это было отсортировано по имени, вам нужно было бы сделать (предполагая, что GNU find и cpio):

find . -type f -print0 | sort -z | \
  cpio --create --null --format=ustar -O /somedir/all.tar

Это имеет тот недостаток, что подкаталоги размещаются между именами файлов. Вы можете проделать трюки с finds -printf0, указав каталог и информацию о глубине, а также отсортировав их, sort -nно это также влияет на порядок сортировки файлов с номерами в каталоге.

Если вышесказанное неудовлетворительно, вы, вероятно, могли бы использовать небольшую программу на основе Python os.walk()для генерации требуемого порядка с полным контролем (сначала глубина, основанная на расширении и т. Д.), Но если вы пойдете по этому пути, вы можете также отбросить cpioи выписать tarфайл с tarfileмодулем Python .

Энтон
источник
1
--null указывает, что -T принимает строки с нулевым символом в конце.
Псуси