Using find and tar with files with special characters in the name

Use the -T feature of tar to tell it to read the list of files from another file (tar treats each line as a separate file).

You can then use <() notation to have your shell generate a pseudo-file from the output of a command:

tar cf ctlfiles.tar -T <(find /home/db -name "*.ctl")

If your shell does not support <() notation, you can use a temporary file:

find /home/db -name "*.ctl" > ctlfile-list
tar cf ctlfiles.tar -T ctlfile-list
rm ctlfile-list

You can use the -print0 feature of find with the -0 feature of xargs, like this:

find /home/db -name '*.ctl' -print0 | xargs -0 tar -cf ctlfiles.tar

-print0 (that's hyphen-print-zero) tells find to use a null as the delimiter between paths instead of spaces, and -0 (that's hyphen zero) tells xargs to expect the same.

Edited to add:

If you have a large number of files, xargs may invoke tar more than once. See comments for ways to deal with that, or make find invoke tar directly, like this, which works with any number of files, even if they have spaces or newlines in their names:

rm -f ctlfiles.tar
find /home/db -name '*.ctl' -exec tar -rf ctlfiles.tar {} +

When the argument following "-T" is "-", the list of files is taken from stdin. Recent versions of tar typically support the "-null" option, which indicates that the files given in the source specified by the "-T" option are null-separated.

Hence the following works with an arbitrary number of files, possibly containing newline characters:

find /home/db -name '*.ctl' -print0 | tar --null -T - -cf ctlfiles.tar

Tags:

Linux

Unix

Find

Tar