find
can take -o
for "or", so you can combine your two find
commands like so:
find . \( -type f -o -type d -empty \) -print0 | tar ...
Or, if you can guarantee all the files can fit on one command line,
find . \( -type f -o -type d -empty \) -exec tar cvfz files.tgz {} +
You can use this command to backup all your dotfiles (.<something>
) in your $HOME
directory:
$ cd ~
$ find . -maxdepth 1 -type f -name ".*" -exec tar zcvf dotfiles.tar.gz {} +
regex using just tar?
method #1
I researched this quite a bit and came up empty. The limiting factor would be that when tar
is performing it's excludes, the trailing slash (/
) that shows up with directories is not part of the equation when tar is performing its pattern match.
Here's an example:
$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*/'} .*
.qalculate/
.qt/
.qterm/
.qtoctave/
.RapidSVN
.RData
.Rhistory
This variant includes an exclude of .*/
and you can see with the verbose switch turned on to tar, -v
, that these directories are passing through that exclude.
method #2
I thought maybe the switches --no-wildcards-match-slash
or --wildcards-match-slash
would relax the greediness of the .*/
but this had no effect either.
Taking the slash out of the exclude, .*
wasn't an option either since that would tell tar
to exclude all the dotfiles and dotdirectories:
$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*'} .*
$
method #3 (Ugly!)
So the only other alternative I can conceive is to provide a list of files to tar
. Something like this:
$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --wildcards-match-slash --exclude={'.','..','.*/'} $(ls -aF | grep -E "^\..*[^/]$")
.RapidSVN
.RData
.Rhistory
This approach has issues if the number of files exceeds the maximum amount of space for passing arguments to a command would be one glaring issue. The other is that it's ugly and overly complex.
so what did we learn?
There doesn't appear to be a straight-forward and elegant way to acomplish this using tar
& regular expressions. So as to @terdon's comment, find ... | tar ...
is really the more appropriate way to do this.
Best Answer
You can use
-C
multiple times (moving from one directory to another):Note that each
-C
option is interpreted relative to the current directory at that point (or you can just use absolute paths).