Извлеките несколько файлов .tar.gz одним вызовом tar

35

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

Я опытный пользователь Unix в течение нескольких лет и, конечно, я знаю, что вы можете использовать forили findили что-то подобное, чтобы вызывать tarодин раз для каждого архива, который вы хотите извлечь, но я не смог придумать рабочую командную строку, которая вызывала мой tarизвлечь два файла .tar.gz одновременно. (И нет, в этом нет ничего плохого for, я просто спрашиваю, можно ли обойтись без него.)

Я задаю этот вопрос скорее из любопытства, может быть

  • есть странная развилка tarгде-то, которая поддерживает это
  • кто-то знает, как использовать -Mпараметр, который tarпредложил мне, когда я пыталсяtar -zxv -f a.tgz -f b.tgz
  • мы все слепы, и это совершенно легко сделать - но я не смог найти в Интернете ни одного намека, который бы не использовал forили findили xargsи тому подобное.

Пожалуйста, не отвечайте с tar -zxvf *.tar.gz(потому что это не работает), и отвечайте только «не работает», если вы абсолютно уверены в этом (и, возможно, у вас есть хорошее объяснение, почему тоже).

Изменить: мне было указано на ответ на этот вопрос о переполнении стека, который очень подробно говорит, что это невозможно без нарушения текущего tarсинтаксиса, но я не думаю, что это правда. Использование tar -zxv -f a.tgz -f b.tgzили tar -zxv --all-args-are-archives *.tar.gzне нарушит существующий синтаксис, imho.

SCY
источник
Из любопытства, в какой ситуации вы начали думать о том, как избежать зацикливания конструкции?
Unclejamil
1
К сведению: GNU tar поддерживает многотомные архивы tar с -Mпараметром.
Стив
1
unclejamil: я пишу HowTo, и один из шагов в нем включает распаковку нескольких сжатых файлов (.tar.bz2, .tar.gz, .zip). И поскольку это HowTo, мне было интересно, какой будет самая элегантная командная строка. :)
scy

Ответы:

39

Это возможно, синтаксис довольно прост:

$ cat *.tar | tar -xvf - -i

Опция -i игнорирует EOF в конце архивов tar со страницы man:

-i, --ignore-zeros
ignore blocks of zeros in archive (normally mean EOF)
многочлен
источник
1
Казалось, это работает для меня. Точная команда , которую я использовал , была: cat *.tar.bz2 | tar -ixjv. Благодарность!
scy
1
<For tgz> cat * .tgz | tar -xzvf - -i -C / destination / <или> для файла в * .tgz; сделать tar -xzvf $ file -C / destination /; сделано
Ferroao
27

для * .tar.gz

for file in *.tar.gz; do tar -zxf "$file"; done

для * .tar.bz2

for file in *.tar.bz2; do tar -jxf "$file"; done

для * .tar.xz

for file in *.tar.xz; do tar -Jxf "$file"; done
Ratnesh
источник
1
Исправьте форматирование здесь, и это будет более читабельным.
eyoung100
это здорово. формат также
хорош,
1
Не забудьте поставить кавычки, $fileесли ваши файлы имеют имена с пробелами.
Александр Рево
Это на самом деле не отвечает на вопрос, возможно ли извлечь несколько архивов, используя один вызов tar. Кроме того, пользователь говорит, что он уже знаком с тем, как использовать циклы for для перебора набора файлов.
Кусалананда
2

Вам нужно использовать цикл. Это не нарушило бы tarсинтаксис командной строки, чтобы разрешить несколько -fопций, но потребовало бы добавления кода для последовательной обработки нескольких архивов со всеми видами граничных условий (Что произойдет, если архив в середине искажен? Могут ли архивы использовать разные механизмы сжатия? У вас может быть несколько -Cопций (опция tar GNU для извлечения в конкретный каталог)? Как насчет -K (опция tar GNU, начинающаяся с определенного имени члена)?…).

Одна возможность избежать forцикла - это установить и активировать AVFS , файловую систему FUSE, которая обеспечивает прозрачный доступ к архивам. Каждый архив /path/to/archiveдублируется как каталог ~/.avfs/path/to/archive#. Если вы хотите сопоставить архивы с подстановочными знаками, есть препятствие добавить это #к сопоставлению с подстановочными знаками; это можно сделать в зш.

mountavfs
cp -p ~/.avfs$PWD/{a,b}.tgz\#/* /destination
cp -p ~/.avfs/path/to/source/*.tgz(e\''REPLY=$REPLY\#'\')/* /destination
Жиль "ТАК - прекрати быть злым"
источник
-1

find . -name "*.tar.gz" -exec tar xzf {} \;

zjengjie
источник
что это делает?
Pierre.Vriens
1
Это вводит неявный цикл, вызывающий tar один раз для каждого найденного файла, и пользователь говорит, что он уже знает, как это сделать.
Кусалананда
Извините, я не прочитал вопрос внимательно, я просто искал способ извлечь несколько пакетов tar, прочитал ответ выше и думаю, что найти будет проще.
zjengjie