filter in "find" ignored when output fed to tar
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.
With GNU tar, you can also use the --exclude
option to exclude files based on names.
$ tar --exclude "*1*" --exclude "*2*" -cvf foo.tar test/
test/
test/3/
There's also -X
or --exclude-from
which takes a file from which to read the exclusion patterns.
Though as find -not -path "*1*"
, this will also exclude files whose names contain a 1
or 2
. To only skip directories whose names match the pattern, use find -prune
and tar --no-recursion
:
$ touch test/3/blah.1
$ find test/ -type d \( -name "*1*" -o -name "*2*" \) -prune -o -print |
tar cvf test.tar --files-from - --no-recursion
test/
test/3/
test/3/blah.1
(At least GNU tar and FreeBSD tar have --no-recursion
)