2010-04-08 4 views
50

Как я могу передать информацию в tar с указанием имен файла?Как я могу создать tar из stdin?

+0

Я думаю, что @geekosaur следует отметить, потому что это ответ, который лучше соответствует вопросу. –

+0

Я изменил выбранный вами ответ. –

ответ

80

Что-то вроде:

tar cfz foo.tgz -T - 

Но имейте в виду, что это не будет работать для всех возможных имен файлов; вы должны рассмотреть опцию --null и подать tar от find -print0. (The xargs пример не совсем работа для больших списков файлов, так как это будет порождать множество tar команд.)

5

Вместо того, чтобы использовать трубу можно использовать кавычку, например:

tar cvzf archive.tgz `ls -1 *` 

Вместо ls -1 * вы можете поставить любую другую команду, которая производит список необходимых для архивации файлов

+10

Единственное, что это не будет работать, если вывод команды ls длиннее максимально допустимого размера командной строки оболочки. В таком случае вы должны сделать это, как говорят один из других ответов; что позволяет сделать список произвольно длинным. Кроме того, «find [...] -print0» позволяет вам создать файл tar, который имеет элементы со специальными символами, где в методе ls нет. Этот метод не так безопасен или универсален. –

3
find /directory > filename 
tar -T filename -cf archive.tar 
20

Как уже указывалось на geekosaur, нет необходимости в трубе выход find к xargs потому, что он можно подключить выход find непосредственно к tar с использованием find ... -print0 | tar --null ....

Обратите внимание на небольшие различия между gnutar и bsdtar в исключении архивного файла.

# exclude file.tar.gz anywhere in the directory tree to be tar'ed and compressed 
find . -print0 | gnutar --null --exclude="file.tar.gz" --no-recursion -czf file.tar.gz --files-from - 
find . -print0 | bsdtar --null --exclude="file.tar.gz" -n -czf file.tar.gz -T - 

# bsdtar excludes ./file.tar.gz in current directory by default 
# further file.tar.gz files in subdirectories will get included though 
# bsdtar: ./file.tar.gz: Can't add archive to itself 
find . -print0 | bsdtar --null -n -czf file.tar.gz -T - 

# gnutar does not exclude ./file.tar.gz in current directory by default 
find . -print0 | gnutar --null --no-recursion -czf file.tar.gz --files-from - 
+0

Если найти в текущем каталоге, то просто использовать ../file.tar.gz в качестве адресата достаточно. –

13

Расширение geekosaur answer:

find /directory | tar -cf archive.tar -T - 

Вы можете использовать стандартный ввод с опцией -T.

Обратите внимание, что при фильтрации файлов с помощью некоторого условия (например, -name варианта) вообще нужно исключить директориям в трубе, иначе смола будет обрабатывать все их содержимое, то есть не то, что вы хотите. Таким образом, использование:

find /directory -type f -name "mypattern" | tar -cf archive.tar -T - 

Если вы не используете -type, будут добавлены все содержимое каталогов, соответствующих "mypattern"!

+0

Я думаю, что этот метод лучше других, потому что вы можете передавать все, что выводится на stdout – daks

+0

Возможно, вы захотите рассмотреть вопрос о том, какие типы файлов используются с помощью 'find'. В частности, я бы сделал 'find -type f'. Это приведет к отключению символических ссылок, символьных устройств и т. Д. Если вас интересуют пустые каталоги, чем 'find -type f -o-type d'. – JamesThomasMoon1979

0

Для лучшего сжатия полезно использовать bzip2.

find $PWD -name "*.doc" > doc.filelist 
tar -cvjf jumbo.tar.bz2 -T doc.filelist 
Смежные вопросы