What is the setting in bash for globbing, to control whether * matches dot files

Bash

As you already noticed bash won't match a . at the start of the name or a slash. To change the matching regarding the dot you have to set the dotglob option - man bash:

dotglob If set, bash includes filenames beginning with a `.'  in
    the results of pathname expansion.

To enable/set it with bash use shopt, e.g:

shopt -s dotglob


For zsh you can also use the dotglob option but but you will have to use setopt to enable it, e.g:

setopt dotglob

* is a glob that is expanded by the shell. By default shells don't include files whose name starts with a . (called hidden files or dotfiles) unless the leading . is entered literally.

* or [.]* or ?* or *.* or dir/* will not include dotfiles.

.* or dir/.* will.

So you could do:

mv -- * .* /dest/

however some shells including bash (but not zsh, mksh nor fish) have that misfeature that the expansion of .* include the . and .. special directory entries, which you don't want here (and generally never want a glob to include which is why I call it a misfeature).

For that reason, you'll find that sometimes people use (in Bourne-like shells):

mv -- * .[!.]* ..?* /dest/

That's three globs, the first one matching non-hidden files, the second one filenames starting with . followed by a character other than . and the 3rd one filenames starting with .. followed by at least one character.

However some modern shells have better ways around that

zsh

With zsh, you can use the (D) glob qualifier to specify that the glob should include dotfiles:

mv -- *(D) /dest/

zsh also fixed that other misfeature of the Bourne shell in that if the pattern doesn't match, the mv command is not run.

As said above it also will never include . nor .. in its globs, so

mv -- * .* /dest/

will be safe. However if there's no file matching * or no file matching .* the command will be aborted, so it would be better to use:

mv -- (*|.*) /dest/

Like in some other shells, you can also force all globs to include dotfiles (for instance if you find yourself wanting dotfiles included more often than not) with:

setopt dotglob

or:

set -o dotglob

After that, if you want a particular glob not to include dotfiles, you can write it:

echo *(^D)

Or:

echo [^.]*

Bash

Unfortunately bash doesn't have glob qualifiers. So you're left with enabling dotfile inclusion globally. In bash, the syntax is:

shopt -s dotglob

(and use [^.]* for globs without hidden files).

With dotglob, bash doesn't include . nor .. in globs like *, but still does for globs like .*.

If you set the GLOBIGNORE variable to something non-empty, it then automatically enables the dotglob option and excludes . and .. from .* globs but not from dir/.* or .*/file ones (!) so that safeguard is pretty useless. You could do GLOBIGNORE='*/.:*/..:./*:../*:*/./*:*/../*' but then it would break globs like */. or ./* or ../*.

A better work around is to use [.]* or dir/[.]* or [.]*/file (with dotglob enabled) to expand dotfiles except . and ...

fish

fish globs don't include . nor ... When there's no match, depending on the version, it will work like either zsh (or bash -o failglob) or bash -o nullglob.

mv -- * .* /dest/

Would work if there are both hidden and non-hidden files. Otherwise, YMMV and with some versions, it may call mv -- /dest if there's no file at all.

ksh93

No glob qualifier in ksh93 either. You can include dotfiles in globs with:

FIGNORE='@(.|..)'

Contrary to bash's GLOBIGNORE, that's done properly and also fixes the problem of .* including . and ...

yash

yash has a dot-glob option (set -o dot-glob), but contrary to bash, the glob expansions (even of *) include . and .. so it's pretty useless.

tcsh

set globdot

Works like in bash, that is * include dot files except . and .. but .* still includes . and .. (and you can use [.]* to expand hidden files except . and ..).


I tested this and it solves the issue:

shopt -s dotglob

Output:

~/stackexchangeanswers/40662$ ls -hal dest
total 8.0K
drwxr-xr-x 2 jodiec jodiec 4.0K 2012-06-12 22:15 .
drwxr-xr-x 4 jodiec jodiec 4.0K 2012-06-12 22:15 ..
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 1
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .1
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 2
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .2
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 3
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .3
...snipped....

Tags:

Bash

Wildcards