tags:

views:

194

answers:

4

I want to create tar file with all the output files resulting from executing find command.

I tried the following command:

find  . \(-name "*.log" -o -name "*.log.*" \) -mtime +7 -exec tar cvf test.tar.gz {} \;

But it is including only the last found file in the test.tar file. How to include all files in test.tar file?

Regards Chaitanya

+1  A: 

You want to pipe the file names found by find into tar.

Don
Yes. You are correct.
Chaitanya MSV
+1  A: 

Use command line substitution:

tar cf test.tar $(find  . \(-name "*.log" -o -name "*.log.*" \) -mtime +7)

What this does is run the command in $() and makes the output the command line arguments of the outer command.

This uses the more modern bash notation. If you are not using bash, you can also use backticks which should work with most shells:

tar cf test.tar `find  . \(-name "*.log" -o -name "*.log.*" \) -mtime +7`

While backticks are more portable, the $() notation is easier if you need to nest command line substitution.

R Samuel Klatchko
This is subject to the shell expansion buffer size limits -- that's what piping avoids.
Don
A: 
find  . \(-name "*.log" -o -name "*.log.*" \) -mtime +7 -exec tar cvf test.tar.gz {} \;

But it is including only the last found file in the test.tar file.

That's because for every file it finds it is running a new tar command that overwrites the tar file from the previous command.

You can make find batch the files together by changing the \; to a + but if there's more files than can be listed at once, find will still run multiple commands, each overwriting the tar file from the previous one. You could pipe the output through xargs but it has the same issue of possibly running the command multiple times. The command line substitution recommended above is the safest way I know of to do it, ensuring that tar can only be called once -- but if too many files are found, it may give an error about the command line being too long.

alanc
A: 

This one should equally work:

find  . -name "*.log" -o -name "*.log.*" -mtime +7 -exec tar cvf test.tar {} +

Note the "+" at the end vs "\;".

For a reliable way when a very large number of files will match the search:

find  . -name "*.log" -o -name "*.log.*" -mtime +7 > /tmp/find.out
tar cvf test.tar -I /tmp/find.out
jlliagre