How can I pipe information into tar
specifying the names of the file?

- 10,882
- 11
- 60
- 114

- 5,838
- 7
- 42
- 67
-
I think @geekosaur should be ticked because is the response which better match the question. – Manolo Carrasco Moñino Sep 25 '13 at 08:33
-
I've changed the selected answer you are right. – Kristopher Ives Oct 04 '13 at 03:02
7 Answers
Something like:
tar cfz foo.tgz --files-from=-
But keep in mind that this won't work for all possible filenames; you should consider the --null
option and feed tar
from find -print0
. (The xargs
example won't quite work for large file lists because it will spawn multiple tar
commands.)
-
-
@PeterMortensen install gnu tar or bsd tar? You'll need to check what name it might go by on the HP-UX app store... – ahron Nov 25 '18 at 04:51
-
Note that if you want to pipe through `sort` when using `find`'s `-print0` option and `tar`'s `--null` option as described, you will also need to supply the `-z` option to `sort`. – Steve Jorgensen Mar 12 '20 at 00:23
As already pointed out by geekosaur, there is no need to pipe the output of find
to xargs
because it is possible to pipe the output of find
directly to tar
using find ... -print0 | tar --null ...
.
Note the slight differences between gnutar
and bsdtar
in excluding the archive file though.
# 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 -

- 231
- 2
- 2
-
If finding in the current dir, then just using ../file.tar.gz as destination is sound enough. – Johan Boulé Dec 12 '16 at 02:22
-
Extending geekosaur answer:
find /directory | tar -cf archive.tar -T -
You can use stdin with the -T
option.
Note that if you filter files using some condition (e.g. -name
option) in general you need to exclude directories in the pipe, otherwise tar will process all their content, that is not what you want. So, use:
find /directory ! -type d -name "mypattern" | tar -cf archive.tar -T -
If you don't use -type
, all the content of directories matching "mypattern"
will be added !

- 2,819
- 3
- 33
- 60

- 191
- 1
- 2
-
I think this method is better that others, because you can pipe anything that outputs to stdout – daks Sep 17 '13 at 07:20
-
1You may want to consider being specific about the file types using `find`. Specifically, I would do `find -type f`. This will disclude symlinks, character devices, etc. If you're interested in empty directories than `find -type f -o -type d`. – JamesThomasMoon Sep 30 '15 at 02:32
-
@JamesThomasMoon1979, is not better option to use `find -path dir/to/exclude -prune`? rather then avoiding dir by `type f`? And also, you say `mypattern`, but is not patter but rather globbin, for pattern is better `find -regex "patter"` – Herdsman Jun 03 '20 at 20:22
-
Rather than `-type f` to avoid directories, I recommend `! -type d`. This has the advantage of **not** excluding other items such as symbolic links, fifos, etc. – CODE-REaD Jul 07 '21 at 20:43
find /directory > filename
tar -T filename -cf archive.tar

- 3,720
- 2
- 33
- 42
-
1Will this work for all possible filenames (see [geekosaur's answer](https://stackoverflow.com/questions/2597875/how-can-i-build-a-tar-from-stdin/5200173#5200173))? – Peter Mortensen Jun 27 '18 at 12:53
Instead of using pipe you could use backticks, e.g.:
tar cvzf archive.tgz `ls -1 *`
Instead of ls -1 *
you can put any other command which produces list of needed to archive files

- 8,615
- 10
- 58
- 81
-
15The only thing is that this will not work if the output of the ls command is longer than the shell's maximum allowed command line size. In such an event, you must do it as one of the other answers say; that permits the list to be arbitrarily long. Also, "find [...] -print0" allows you to create a tar file that has members with special characters, where as the ls method doesn't. This method just isn't as safe or universally applicable. – Michael Trausch Oct 16 '12 at 17:33
The tar
program has been implemented in a variety of ways. For example, on IBM's version of Unix, AIX, tar
uses the -L
option rather than -T
, and requires a file rather than allowing -
to indicate stdin:
Usage: tar -{c|r|t|u|x} [ -BdDEFhilmopRUsvwZ ] [ -Number ] [ -f TarFil e ]
[ -b Blocks ] [ -S [ Feet ] | [ Feet@Density ] | [ Blocksb ] ]
[ -L InputList ] [-X ExcludeFile] [ -N Blocks ] [ -C Directory ] File ...
Usage: tar {c|r|t|u|x} [ bBdDEfFhilLXmNopRsSUvwZ[0-9] ] ]
[ Blocks ] [ TarFile ] [ InputList ] [ ExcludeFile ]
[ [ Feet ] | [ Feet@Density ] | [ Blocksb ] ] [-C Directory ] File ...

- 1,019
- 11
- 13
You have to use it different on WINDOWS. Do not use the z
parameter because it causes the "Can't add archive to itself" error. In addition, if you dont use the ".tar" in the Zip file name (when using z
) parameter, tar.exe will create a extensionless file inside the zip file, which is quite useless for most people.
And, i think most people want a single zip file with the files in it, not a zip file with a tar in it. So thats also a reasion not using the z
parameter. However i talk about using tar in Windows, im not familar Linux, may it's different there. So in Windows:
To create a ZIP File inside a directory, with specific files in that directory, use:
tar.exe -cf MyZipFilename.zip file1.txt file2.jpg file3.xyz
To create a ZIP File inside a directory, with wildcard for files in that directory, use:
tar.exe -cf MyZipFilename.zip *.txt *.jpg *.xyzff
To let you view the zipped files, add the v
parameter in between. Examples:
tar.exe -cvf MyZipFilename.zip file1.txt file2.jpg file3.xyz
or
tar.exe -cvf MyZipFilename.zip *.txt *.jpg *.xyzff
To create a ZIP File inside a directory, with all files in that directory, use: (the trick is that --exclude is at the beginning)
tar.exe --exclude MyZipFilename.zip -cf MyZipFilename.zip *
Finally, i dont know why you want to use it, but if you want using z
the command would be:
tar.exe --exclude MyZipFilename.tar.zip -cvzf MyZipFilename.tar.zip *
Just try it out