как вы можете распаковать несколько файлов одновременно?

<p>у меня есть несколько файлов <code>tar</code> в каталоге, и я хочу извлечь из них все файлы одновременно. но это, похоже, ничего не делает:</p><pre><code>$ tar xf .tar что тут происходит? как распаковать кучу файлов одновременно?

что тут происходит?первоначально команда tar предназначалась для использования с устройствами на магнитной ленте. поскольку имеет смысл выполнять tar одновременно только на одном устройстве, синтаксис был разработан для использования одного и только одного устройства. предполагалось, что первым переданным файлом или каталогом будет устройство, в котором находится рассматриваемый архив, и любые другие файлы или каталоги, в которых содержимое архива должно быть включено в операцию. таким образом, для извлечения tar (опция x) первым переданным файлом будет архив, а все остальные файлы будут файлами, которые будут извлечены. поэтому, если есть два файла .tar (скажем, a.tar и b.tar), ваша команда будет расширена до:$ tar xf a.tar b.tar </code></pre><p>если <code>a.tar</code> не содержит файл с именем <code>b.tar</code>, команда <code>tar</code> не имеет ничего общего и тихо завершает работу. досадно, что версия <code>tar</code> для solaris не сообщает о проблемах ни с кодом возврата, ни с подробной опцией (<code>v</code>). между тем, <code>gnu tar</code> возвращает <code>2</code> и спам <code>stderr</code>, даже если опция verbose отключена:</p><pre><code>tar: b.tar: not found in archive tar: exiting with failure status due to previous errors </code></pre><h1>как распаковать кучу файлов одновременно?</h1><p>слишком поздно переписать <code>tar</code>, чтобы принять несколько архивных файлов в качестве входных данных, но это не слишком сложно, чтобы обойти ограничение.</p><p>для большинства людей запуск <code>tar</code> несколько раз для нескольких архивов является наиболее целесообразным вариантом. передача только одного имени файла в <code>tar xf</code> извлечет все заархивированные файлы, как и следовало ожидать. один из подходов заключается в использовании цикла <code>for</code> оболочки:</p><pre><code>$ for f in .tar; do tar xf "$f"; done </code></pre><p>другой метод заключается в использовании <code>xargs</code>:</p><pre><code>$ ls .tar | xargs -i tar xf {} в качестве альтернативы, вы можете использовать один из нескольких <a href="https://stackoverflow.com/questions/484133/whats-a-good-tar-utility-for-windows">альтернативные tar файловые ридеры . наконец, действительно преданный программист может легко написать замену tar, которая работает именно так, как нужно. <a href="http://www.mkssoftware.com/docs/man4/tar.4.asp">формат является простым, и многие языки программирования имеют библиотеки, доступные для чтения tar файлов. например, если вы программист на perl, взгляните на модуль <a href="http://perldoc.perl.org/archive/tar.html">archive::tar .предупреждениеслепая распаковка файлов может вызвать неожиданные проблемы. наиболее очевидным является то, что конкретное имя файла может быть включено в несколько файлов tar. поскольку tar перезаписывает файлы по умолчанию, точная версия файла, с которым вы работаете, будет зависеть от порядка обработки архивов. больше проблем, вы можете получить поврежденную копию файла, если попробуете эту "умную" оптимизацию:for f in .tar; do tar xf "$f" & done wait </code></pre><p>если и <code>a.tar</code>, и <code>b.tar</code> содержат один и тот же файл и пытаются извлечь его одновременно, результаты непредсказуемы.</p><p>связанная проблема, особенно при получении архивов из ненадежного источника, связана с возможностью <a href="http://www.linfo.org/tarbomb.html">tarbomb</a> .</p><p>одним из частичных решений было бы автоматическое создание нового каталога для извлечения в:</p><pre><code>for f in *.tar; do d=`basename "$f" .tar mkdir "$d" (cd "$d" && tar xf "../$f") done </code></pre><p>это не поможет, если файл указан в архиве с абсолютным путем (что обычно является признаком злонамеренного намерения). добавление такого рода проверки остается в качестве упражнения для читателя.</p>

<p>если все файлы tar находятся в одной папке, я делаю это в командной оболочке tcsh. работает все время.</p><pre><code>find -iname \*.tar -exec tar -xvf {} \; </code></pre><p>это то же самое, что и приведенный выше ответ, я думаю, что он более лаконичен.</p>

<pre><code>find . -maxdepth 1 -name '*.tar' -exec tar -xf '{}' \; </code></pre>