Linux gzip несколько подкаталогов в отдельные архивы?

16

Как я смогу сжать подкаталоги в отдельные архивы?

Пример:

directory
 subdir1
 subdir2

Должны создать subdir1 (.tar) .gz и subdir2 (.tar) .gz

EarthMind
источник

Ответы:

27

Этот небольшой скрипт кажется вашим лучшим вариантом, учитывая ваши требования:

cd directory
for dir in */
do
  base=$(basename "$dir")
  tar -czf "${base}.tar.gz" "$dir"
done

Он правильно обрабатывает каталоги с пробелами в их именах.

Жулиано
источник
Это дает мне эту ошибку: bash: -c: строка 1: синтаксическая ошибка: неожиданный конец файла
EarthMind
@EarthMind: здесь все отлично работает. Проверьте, правильно ли был скопирован скрипт.
Джулиано,
@EarthMind: Я не уверен, что вы правильно изложили оригинальный вопрос. Вы хотите запустить это снова и получить новые файлы .tar.gz, оставив только предыдущие файлы .tar.gz? Попробуйте добавить «tmstamp = $ (date '+% Y% m% d-% H% M')» и измените $ {base} на $ {base} - $ {tmstamp}.
Freiheit
2
@EarthMind: если вы собираетесь поместить все в одну строку, убедитесь, что перед командой tar стоит точка с запятой (;). В противном случае base передается tar как переменная окружения, а не как вспомогательная переменная оболочки.
Джулиано
@mwojtera ваша попытка редактирования должна быть ее собственным ответом
цыпочки
10

Как насчет этого: find * -maxdepth 0 -type d -exec tar czvf {}.tar.gz {} \;

Объяснение: Вы запускаете поиск для всех элементов в текущем каталоге. Maxdepth 0 заставляет его не повторяться ниже приведенных аргументов. (В этом случае * или все элементы в вашем текущем каталоге) Аргумент '-d' для -type соответствует только каталогам. Затем exec запускает tar при любых совпадениях. ({} заменяется соответствующим файлом)

Кристофер Карел
источник
1
Но тогда я все еще получаю ошибку, что данный путь является каталогом, а не файлом
EarthMind
3
Один только gzip не архивирует каталоги
Juliano
Вам нужно скопировать каталоги, прежде чем вы сможете их сжать.
ℝaphink
1
Вам нужен tar с опцией z, а не прямой gzip для каталогов. Очень хорошее использование find.
Freiheit
3
Ошибка: «find: пути должны предшествовать выражению:;» Первая часть работает, поэтому я использовал (только каталоги): for dir in `find * -maxdepth 0 -type d`; do tar -cvzf ${dir}.tar.gz ${dir}; done
JosephK
4

Это создаст файл с именем blah.tar.gz для каждого файла в каталоге с именем blah.

$ cd directory
$ for dir in `ls`; do tar -cvzf ${dir}.tar.gz ${dir}; done

Если у вас есть больше, чем просто каталоги в каталоге (то есть файлы, а ls вернет все в каталоге), используйте это:

$ cd directory
$ for dir in `find . -maxdepth 1 -type d  | grep -v "^\.$" `; do tar -cvzf ${dir}.tar.gz ${dir}; done

Grep -v исключает текущий каталог, который будет отображаться в findкоманде по умолчанию.

Филип Рейнольдс
источник
3
И ls, и find НЕ предназначены для такого использования. В частности, он предназначен для представления файлов в читабельном для пользователя списке, а не для создания списков файлов в качестве аргументов для «для». Просто используйтеfor dir in *
Juliano
1
Я попробовал ваше первое предложение, но оно не работает с каталогами, содержащими пробелы в их названии
EarthMind
Кроме того, первая команда также создаст архив для каждого файла в каталоге.
ℝaphink