Filter in “find” ignored when output fed to tar

findrecursivetar

I have the following directory structure:

test/
test/1/
test/foo2bar/
test/3/

I want to compress directory "test" excluding everything which is in subdirectories (depth not predefined), which include strings "1" or "2" in them. In bash shell, i want to use find and feed its output to tar. I first test find:

find test/ -not -path "*1*" -not -path "*2*"

Output:

test/
test/3

Great. So i combine it with tar:

find test/ -not -path "*1*" -not -path "*2*" | tar -czvf test.tar.gz --files-from -

Output:

test/
test/3/
test/1/
test/foo2bar/
test/3/

Indeed, both "test/1" and "test/foo2bar" are present in the archive. Why were these arguments passed to tar, if they were not supposed to be present in find output?

Best Answer

To expand on what @cuonglm said, tar by default operates recursively. If you pass it a directory name, it will archive the contents of that directory.

You could modify your find command to return only the names of files, not directories...

find test/ -type f -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --files-from -

You could instead use the --no-recursion flag to tar:

find test/ -not -path "*1*" -not -path "*2*" | 
tar -czvf test.tar.gz --no-recursion --files-from - 

Which results in:

test/
test/3/

The --no-recursion flag is specific to GNU tar. If you're using something else, consult the appropriate man page to see if there is a similar feature available.

Note that your find command will exclude files that contain 1 or 2 in the path as well as directories.