tar: добавить все файлы и каталоги в текущий каталог, включая .svn и т. д.

<p>я пытаюсь tar.gz каталог и использовать</p><pre><code>tar -czf workspace.tar.gz * </code></pre><p>полученный tar включает в себя каталоги <code>.svn</code> в подкаталогах, но не в текущем каталоге (так как <code>*</code> раскрывается только в «видимые» файлы перед передачей в tar</p><p>я пытался </p><p>вместо этого <code>tar -czf workspace.tar.gz .</code>, но тогда я получаю ошибку, потому что '.' изменилось при чтении:</p><pre><code>tar: ./workspace.tar.gz: file changed as we read it </code></pre><p>есть ли хитрость, чтобы <code>*</code> соответствовал всем файлам (включая префикс с точкой) в каталоге?</p><p>(использование bash в linux sles-11 (2.6.27.19)</p>

<p>не создавайте файл tar в каталоге, который вы упаковываете:</p><pre><code>tar -czf /tmp/workspace.tar.gz . </code></pre><p>делает трюк, за исключением того, что он будет распаковывать файлы по всему текущему каталогу при распаковке. лучше сделать:</p><pre><code>cd .. tar -czf workspace.tar.gz workspace </code></pre><p>или, если вы не знаете название каталога, в котором вы были:</p><pre><code>base=$(basename $pwd) cd .. tar -czf $base.tar.gz $base </code></pre><p>(это предполагает, что вы не переходили по символическим ссылкам, чтобы добраться до того места, где вы находитесь, и что командная консоль не пытается угадать вас, перепрыгивая через символьную ссылку - <code>bash</code> не заслуживает доверия в этом отношении. если вам приходится беспокоиться об этом , используйте <code>cd -p ..</code>, чтобы сделать каталог физических изменений. глупо, что это, по моему мнению, не поведение по умолчанию - сбивает с толку, по крайней мере, для тех, для которых <code>cd ..</code> никогда не имел никакого альтернативного значения.)</p><hr><p>один комментарий в обсуждении говорит:</p><blockquote> <p>мне нужно [...] исключить верхний каталог, и мне нужно [...] поместить tar в базовый каталог.</p> </blockquote><p>первая часть комментария не имеет особого смысла - если файл tar содержит текущий каталог, он не будет создан при извлечении файла из этого архива, поскольку по определению текущий каталог уже существует (за исключением очень странных обстоятельств ).</p><p>вторая часть комментария может быть рассмотрена одним из двух способов:</p><ol> <li>либо: создайте файл где-нибудь еще - <code>/tmp</code> - это одно из возможных мест - и затем переместите его обратно в исходное место после его завершения.</li> <li>или: если вы используете gnu tar, используйте опцию <code>--exclude=workspace.tar.gz</code>. строка после <code>=</code> является шаблоном - пример - самый простой шаблон - точное совпадение. возможно, вам придется указать <code>--exclude=./workspace.tar.gz</code>, если вы работаете в текущем каталоге вопреки рекомендациям; вам может потребоваться указать <code>--exclude=workspace/workspace.tar.gz</code>, если вы работаете на один уровень выше, чем предложено. если у вас есть несколько файлов tar для исключения, используйте «<code>*</code>», как в <code>--exclude=./*.gz</code>.</li> </ol>

<p>если вы<em> действительно </em>не хотите включать верхний каталог в tarball (и это вообще плохая идея):</p><pre><code>tar czf workspace.tar.gz -c /path/to/workspace . </code></pre>

<p>есть несколько шагов:</p><ol> <li>замените <code>*</code> на <code>.</code>, чтобы включить скрытые файлы.</li> <li>чтобы создать архив в том же каталоге, можно использовать <code>--exclude=workspace.tar.gz</code>, чтобы исключить сам архив.</li> <li>чтобы предотвратить ошибку <code>tar: .: file changed as we read it</code>, когда архив еще не создан, убедитесь, что он существует (например, с использованием <code>touch</code>), поэтому<em> --exclude </em>совпадает с именем файла архива. (не соответствует этому файлу не существует)</li> </ol><p>в сочетании это приводит к следующему сценарию:</p><pre><code>touch workspace.tar.gz tar -czf workspace.tar.gz --exclude=workspace.tar.gz . </code></pre>

<p>в каталоге хотите сжать (текущий каталог) попробуйте это:</p><pre><code>tar -czf workspace.tar.gz . --exclude=./*.gz </code></pre>

<p>вы можете исправить форму <code>.</code>, используя <code>--exclude</code>:</p><pre><code>tar -czf workspace.tar.gz --exclude=workspace.tar.gz . </code></pre>

<p>вы можете включить скрытые каталоги, вернувшись назад в каталог и выполнив:</p><pre><code>cd .. tar -czf workspace.tar.gz workspace </code></pre><p>предполагая, что каталог, который вы хотите gzip, называется рабочим пространством.</p>

<p><strong> обновление: </strong>я добавил исправление для комментария оп.</p><pre><code>tar -czf workspace.tar.gz . </code></pre><p>действительно изменит текущий каталог, но почему бы не разместить файл где-нибудь еще?</p><pre><code>tar -czf somewhereelse/workspace.tar.gz . mv somewhereelse/workspace.tar.gz . # update </code></pre>

<p>на самом деле проблема с вариантами сжатия. хитрость заключается в том, что труба направляется на компрессор вместо использования встроенных опций. кстати, это также может дать вам лучшее сжатие, так как вы можете установить дополнительные параметры сжатия.</p><p>минимальная смола:</p><pre><code>tar --exclude=*.tar* -cf workspace.tar . </code></pre><p>труба к компрессору по вашему выбору. этот пример многословен и использует xz с максимальным сжатием:</p><pre><code>tar --exclude=*.tar* -cv . | xz -9v >workspace.tar.xz </code></pre><p>решение было протестировано на ubuntu 14.04 и cygwin на windows 7 ... это ответ сообщества вики, поэтому не стесняйтесь редактировать, если обнаружите ошибку.</p>

<p>хороший вопрос в zsh вы можете использовать модификатор globbing <code>(d)</code>, который обозначает «точечные файлы». для сравнения:</p><pre><code>ls $home/ а такжеls $home/*(d) </code></pre><p>это правильно исключает специальные записи каталога <code>.</code> и <code>..</code>. в bash вы можете использовать <code>.*</code> для явного включения файлов точек:</p><pre><code>ls $home/ $home/.* </code></pre><p>но это также касается <code>.</code> и <code>..</code>, так что это не то, что вы искали. я уверен, что есть некоторый способ сделать так, чтобы <code>*</code> совпадал с точечными файлами в bash.</p>

<pre><code>tar -czf workspace.tar.gz .??* * </code></pre><p>указание <code>.??*</code> будет включать в себя «точечные» файлы и каталоги, которые имеют как минимум 2 символа после точки. недостатком является то, что он не будет включать файлы/каталоги с одним символом после точки, например, <code>.a</code>, если таковые имеются.</p>

<p>у меня была похожая ситуация. я думаю, что лучше создать tar в другом месте, а затем использовать -c, чтобы указать tar базовый каталог для сжатых файлов. пример:</p><pre><code>tar -cjf workspace.tar.gz -c <path\_to\_workspace> $(ls -a <path\_to\_workspace>) </code></pre><p>таким образом, нет необходимости исключать ваш собственный tarfile. как отмечено в других комментариях, -a будет список скрытых файлов.</p>

<p>еще одно решение, при условии, что количество элементов в папке невелико:</p><pre><code>tar -czf workspace.tar.gz `ls -a` </code></pre><p>(<code>ls -a</code> печатает обычные и скрытые файлы, но не "." и "..", как <code>ls -a</code>.)</p>

<p>проблема с большинством решений, представленных здесь, состоит в том, что tar содержит <code>./</code> в начале каждой записи. таким образом, это приводит к наличию каталога <code>.</code> при открытии его через компрессор gui. итак, что я в итоге сделал:</p><p><code>ls -1a | xargs -d "\n" tar cfz my.tar.gz</code></p><p>если у вас уже есть <code>my.tar.gz</code> в текущем каталоге, вы можете использовать это:</p><p><code>ls -1a | grep -v my.tar.gz | xargs -d "\n" tar cfz my.tar.gz</code></p><p><strong> имейте в виду </strong>что xargs имеет определенные ограничения (см. <code>xargs --show-limits</code>). таким образом, это решение не будет работать, если вы пытаетесь создать пакет, который содержит много записей (каталогов и файлов) в каталоге, который вы пытаетесь скопировать.</p>

<p>если пространство на диске не является проблемой, это также может быть очень легко сделать: </p><pre><code>mkdir backup cp -r ./* backup tar -zcvf backup.tar.gz ./backup </code></pre>