5

Я хочу заархивировать все .ctl файлы в папке, рекурсивно.

tar -cf ctlfiles.tar `find /home/db -name "*.ctl" -print`

Сообщение об ошибке:

tar: Removing leading `/' from member names
tar: /home/db/dunn/j: Cannot stat: No such file or directory
tar: 74.ctl: Cannot stat: No such file or directory

У меня есть эти файлы: /home /db /dunn /j 74.ctl и j 75. Обратите внимание на дополнительное место. Что если в файлах есть другие специальные символы? Как я могу архивировать эти файлы рекурсивно?

3 ответа3

5

Используйте опцию -T в tar, чтобы сказать ему, чтобы он читал список файлов из другого файла (tar рассматривает каждую строку как отдельный файл).

Затем вы можете использовать нотацию <() чтобы ваша оболочка генерировала псевдофайл из вывода команды:

tar cf ctlfiles.tar -T <(find /home/db -name "*.ctl")

Если ваша оболочка не поддерживает нотацию <() , вы можете использовать временный файл:

find /home/db -name "*.ctl" > ctlfile-list
tar cf ctlfiles.tar -T ctlfile-list
rm ctlfile-list
4

Вы можете использовать функцию -print0 find с функцией -0 в xargs, например так:

find /home/db -name '*.ctl' -print0 | xargs -0 tar -cf ctlfiles.tar

-print0 (это дефис-принт-ноль) указывает, что find использует null в качестве разделителя между путями вместо пробелов, а -0 (это дефис ноль) говорит xargs ожидать того же.

Отредактировано, чтобы добавить:

Если у вас есть большое количество файлов, xargs может вызывать tar несколько раз. Смотрите комментарии, чтобы узнать, как с этим справиться, или заставьте find вызывать tar напрямую, например так, который работает с любым количеством файлов, даже если в их именах есть пробелы или переводы строк:

rm -f ctlfiles.tar
find /home/db -name '*.ctl' -exec tar -rf ctlfiles.tar {} \;

Но, вероятно, он менее эффективен, поскольку он вызывает tar (в режиме добавления) один раз для каждого файла.

1

Если аргумент, следующий за «-T», равен «-», список файлов берется из stdin. Последние версии tar обычно поддерживают параметр «-null», который указывает, что файлы, указанные в источнике, указанном параметром «-T», разделяются нулями.

Следовательно, следующее работает с произвольным количеством файлов, возможно, содержащих символы новой строки:

find /home/db -name '*.ctl' -print0 | tar --null -T - -cf ctlfiles.tar

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