Как вы можете распаковать несколько файлов одновременно? - PullRequest
64 голосов
/ 25 февраля 2009

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

$ tar xf *.tar

Что здесь происходит? Как распаковать сразу несколько файлов?

Ответы [ 3 ]

128 голосов
/ 25 февраля 2009

Что здесь происходит?

Изначально команда tar предназначалась для использования с устройствами на магнитной ленте. Поскольку имеет смысл выполнять tar только на одном устройстве за раз, синтаксис был разработан для использования одного и только одного устройства. Предполагалось, что первым переданным файлом или каталогом будет устройство, в котором находится рассматриваемый архив, и любые другие файлы или каталоги, в которых содержимое архива будет включено в операцию. Таким образом, для извлечения tar (опция x) первым переданным файлом будет архив, а все остальные файлы будут файлами, которые будут извлечены. Таким образом, если есть два *.tar файла (скажем, a.tar и b.tar), ваша команда расширится до:

$ tar xf a.tar b.tar

Если a.tar не содержит файл с именем b.tar, команда tar не имеет ничего общего и тихо завершает работу. Досадно, что версия Solaris tar не сообщает о каких-либо проблемах ни с кодом возврата, ни с подробной опцией (v). Между тем, GNU tar возвращает 2 и спам STDERR даже при выключенной опции verbose:

tar: b.tar: Not found in archive
tar: Exiting with failure status due to previous errors

Как распаковать сразу несколько файлов?

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

Для большинства людей запуск tar несколько раз для нескольких архивов является наиболее целесообразным вариантом. Передача только одного имени файла в tar xf извлечет все архивные файлы, как и следовало ожидать. Одним из подходов является использование оболочки for loop:

$ for f in *.tar; do tar xf "$f"; done

Другой способ - использовать xargs:

$ ls *.tar | xargs -i tar xf {}

В качестве альтернативы, вы можете использовать одну из нескольких альтернативных tar программ для чтения файлов . Наконец, по-настоящему преданный программист может легко написать замену tar, которая работает точно так, как нужно. Формат прост, и многие языки программирования имеют библиотеки для чтения файлов tar. Если вы, например, программист на Perl, взгляните на модуль Archive::Tar.

Предупреждение

Слепое извлечение нескольких файлов может вызвать непредвиденные проблемы. Наиболее очевидным является то, что конкретное имя файла может быть включено в более чем один tar файл. Поскольку tar перезаписывает файлы по умолчанию, точная версия файла, с которым вы работаете, будет зависеть от порядка обработки архивов. Больше проблем, вы можете получить поврежденную копию файла, если попробуете эту «умную» оптимизацию:

for f in *.tar; do
  tar xf "$f" &
done
wait

Если и a.tar, и b.tar содержат один и тот же файл и пытаются извлечь его одновременно, результаты непредсказуемы.

Связанная проблема, особенно при получении архивов из ненадежного источника, заключается в возможности тарбомбы .

Одним из частичных решений было бы автоматическое создание нового каталога для извлечения в:

for f in *.tar; do 
  d=`basename "$f" .tar`
  mkdir "$d"
  (cd "$d" && tar xf "../$f")
done

Это не поможет, если файл указан в архиве с абсолютным путем (что обычно является признаком злонамеренного намерения). Добавление такого рода проверки оставлено читателю в качестве упражнения.

11 голосов
/ 01 января 2016

Если все файлы tar находятся в одной папке, я делаю это в оболочке tcsh. Работает все время.

find -iname \*.tar -exec tar -xvf {} \;

Это то же самое, что и приведенный выше ответ, я думаю, что он немного более краткий.

4 голосов
/ 12 июня 2014
find . -maxdepth 1 -name '*.tar' -exec tar -xf '{}' \;
...