Reputation: 1284
I want to tar a directory that looks like this:
dir
└── workspace
└── node_modules
└── subfolder
└── workspace
└── node_modules
└── other_folder
I want to exclude all folders named node_modules
and exclude the top level folder called workspace
, but no sub folders called workspace
.
So what I want to end up with is this:
dir
└── subfolder
└── workspace
└── other_folder
I'm running this command: tar -czf ./output.tar.gz --exclude=node_modules --exclude=./workspace dir/.
But it's removing all folders called workspace and node_modules, so I instead end up with this:
dir
└── subfolder
└── other_folder
How do I remove only the specific workspace folder that I want, and not all folders with the same name?
Upvotes: 3
Views: 5277
Reputation: 14422
For the required case, possible to use tar excludes:
--exclude dir/./folder
-- apply to folder directly under dir--exclude folder
-- will exclude folder anywhere in the treeShould be possible to use:
tar -czf ./output.tar.gz --exclude=node_modules --exclude=dir/./workspace dir/.
Of course possible to use --files-from
, and to generate the list using another tool. This is usually preferred when the list could be large number of files, vs using xargs
.
find dir/. -type f ... | tar cvz ./output.tar.gz -T-
Upvotes: 2
Reputation: 140900
find
has many, many, many options for including, excluding paths, files, directories, generally filtering options however you want to.
For your case I think it would be:
# exclude all folders named node_modules
# exclude the top level folder called workspace
# but no sub folders called workspace
find dir -type f \
-not -regex '.*/node_modules/.*' -a \
-not -regex 'dir/workspace/.*' \
-exec tar -czf ./output.tar.gz {} +
You may prefer instead of -exec
for example find ... -print0 | xargs -0 tar -czf ./output.tar.gz
. I think the best would be find ... -print0 | tar -czf ./output.tar.gz --null -T -
as it will not fail if there are too many files, ie. too many arguments to pass to tar
, I think.
I recreated dir
directory with:
while read l; do
mkdir -p "$(dirname "$l")"
touch "$l"
done <<EOF
dir/workspace/1.txt
dir/node_modules/2.txt
dir/subfolder/workspace/3.txt
dir/subfolder/node_modules/4.txt
dir/subfolder/other_folder/5.txt
EOF
then tested on repl and the tar -tf ./output.tar.gz
prints:
dir/subfolder/workspace/3.txt
dir/subfolder/other_folder/5.txt
Upvotes: 1