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....