How to combine the 'tar' command with 'find'
You can use something like:
find var/log -iname 'anaconda.*' -print0 | tar -cvf somefile.tar --null -T -
The -print0
and -T
work together to allow filenames with spaces newlines, etc. The final -
tells tar to read the input filenames from stdin.
Note that -print0
must come at the end of your statement, per this answer. Otherwise you will probably get more files than you expect.
Note: See @Iain's answer for a somewhat more efficient solution.
Note that find
will call the -exec
action for every single file it finds.
If you run tar -cvf file.tar {}
for every single file find
outputs, this means you'll overwrite file.tar
every time, which explains why you end up with one archive left that only contains anaconda.storage.log
— it's the last file find
outputs.
Now, you actually want to append the files to the archive instead of creating it each time (this is what the -c
option does). So, use the following:
find var/log/ -iname "anaconda.*" -exec tar -rvf file.tar {} \;
The -r
option appends to the archive instead of recreating it every time.
Note: Replace -iname anaconda.*
with -iname "anaconda.*"
. The asterisk is a wildcard and can be expanded by your shell before find
even sees it. To prevent this expansion, wrap the argument in double quotes.
As for tar
removing leading /
: The archive should only contain relative file names. If you added files with a leading /
, they would be stored as absolute file names, literally meaning /var/…
on your computer, for example.
IIRC this is simply a precaution for tar
implementations other than GNU, and it's safer this way because you won't overwrite your actual data in /var/…
when you extract the archive if it contains relative filenames.
Try this:
tar -cvf file.tar `find var/log/ -iname "anaconda.*"`
You were trying to use find
to -exec tar
. But the way the -exec
option works, it runs that command once for each matching file it finds, causing tar
to overwrite the tar file it produces each time. That's why you only ended up with the last one. Also, you need to put quotes around the pattern you specify to find
so that the shell doesn't expand it before passing it to find
.
Using command substitution with backticks (or using $(...)
notation if you prefer), the entire list of names produced by find
is pasted back onto the command line as arguments to tar
, causing it to write them all at once.