I want to backup all the 'dotfiles' (f.e. .zshrc) under my home directory with tar, but excluding the directory structure and all subdirectories.

I've tried it several times with different commands, but the best i achieved was an archive which included the hidden directories under $HOME as well.

tar --create --file=$HOME/$BACKUPFILE --auto-compress --no-recursion --exclude=. --exclude=.. --exclude=*/ --directory=$HOME .*

I also thought about using find and piping the result to tar, but with no luck. Does somebody know how to achieve this - seemingly easy - task?

PS: Most of the time when I'm using tar to create an archive, i have to think about xkcd comic:

xkcd 1168 :)

  • The answer of sim works, but if someone got a regex that matches only the hidden files, please post it!
    – klingt.net
    Commented Jul 19, 2013 at 15:05
  • 1
    Surely this would be better achieved with your shell. I understand that zsh has globs that select only files -- *(.) -- and I think it excludes . and .. from .* by default (and they wouldn't be picked up by .*(.) anyway, since it selects only files). I don't use zsh myself, so I'm not sure enough to turn this into an answer.
    – evilsoup
    Commented Jul 19, 2013 at 20:20

4 Answers 4


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={'.','..','.*/'} .*

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 "^\..*[^/]$")

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.

  • I really wanted to get it done with regex, but i should have known that it won't work that way :)
    – klingt.net
    Commented Jul 19, 2013 at 15:04
  • @klingt.net - it should be possible, I'm looking now.
    – slm
    Commented Jul 19, 2013 at 15:05
  • @klingt.net why would you prefer the more complicated way? Using regex you will probably need to escape the leading dot and will have trouble ignoring . and ... I am sure it is possible as slm will probably demonstrate but I don't see why it would be worthwhile.
    – terdon
    Commented Jul 19, 2013 at 15:08
  • 1
    @klingt.net - everything that the find command finds get's passed as an argument to tar. The {} says where you want those results to go in the corresponding -exec command. The + says to add as many results from find as will fit on the command line and call tar only a couple of times rather than every time a result is found.
    – slm
    Commented Jul 19, 2013 at 15:12
  • 1
    @klingt.net - there isn't a way to accomplish this using regex and tar because there is no way to isolate the dot directories (.blah/). Tar doesn't use the trailing slash when doing the exclude.
    – slm
    Commented Jul 19, 2013 at 15:59

This kind of control over matching files is way outside tar's comfort zone. Its rules for matching files are limited to simple matches over names.

find is one way, but since you have zsh, you have it easier:

tar -cf "$HOME/$BACKUPFILE" --auto-compress .*(.)

That . in parentheses at the end of the wildcard expression is a glob qualifier that says “only match regular files”.

Symbolic links to regular files are not matched. If you change to .*(-.), they will be included, but the file won't end up in the archive unless it's also included. If you want to replace symbolic link by their targets, make that .*(-.:A) — :A adds the history expansion modifier that resolves all symbolic links to a path that doesn't use symbolic links.


This answer is based on slm's, but I will also show you how to include directories beginning with .

To zip up dot files in your home directory:

$ cd
$ find . -maxdepth 1 -type f -name ".?*" -exec tar czfv dotfiles.tgz {} +

To include directories:

$ find . -maxdepth 1 -name ".?*" -exec tar czfv dotfiles.tgz {} +

The ? is optional in the first command, but not in the second, otherwise, find will include the . (current) directory.


what about:

tar -C $HOME -cvzf dotfiles.tgz .

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .