Zsh
mv Foo/*(DN) Bar/
or
setopt -s glob_dots
mv Foo/*(N) Bar/
(Leave out the (N)
if you know the directory is not empty.)
Bash
shopt -s dotglob nullglob
mv Foo/* Bar/
Ksh93
If you know the directory is not empty:
FIGNORE='.?(.)'
mv Foo/* Bar/
Standard (POSIX) sh
for x in Foo/* Foo/.[!.]* Foo/..?*; do
if [ -e "$x" ]; then mv -- "$x" Bar/; fi
done
If you're willing to let the mv
command return an error status even though it succeeded, it's a lot simpler:
mv Foo/* Foo/.[!.]* Foo/..?* Bar/
GNU find and GNU mv
find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- {} +
Standard find
If you don't mind changing to the source directory:
cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "$@" "$0"' ../Bar/ {} + -type d -prune
Here's more detail about controlling whether dot files are matched in bash, ksh93 and zsh.
Bash
Set the dotglob
option.
$ echo *
none zero
$ shopt -s dotglob
$ echo *
..two .one none zero
There's also the more flexible GLOBIGNORE
variable, which you can set to a colon-separated list of wildcard patterns to ignore. If unset (the default setting), the shell behaves as if the value was empty if dotglob
is set, and as if the value was .*
if the option is unset. See Filename Expansion in the manual. The pervasive directories .
and ..
are always omitted, unless the .
is matched explicitly by the pattern.
$ GLOBIGNORE='n*'
$ echo *
..two .one zero
$ echo .*
..two .one
$ unset GLOBIGNORE
$ echo .*
. .. ..two .one
$ GLOBIGNORE=.:..
$ echo .*
..two .one
Ksh93
Set the FIGNORE
variable. If unset (the default setting), the shell behaves as if the value was .*
. To ignore .
and ..
, they must be matched explicitly (the manual in ksh 93s+ 2008-01-31 states that .
and ..
are always ignored, but this does not correctly describe the actual behavior).
$ echo *
none zero
$ FIGNORE='@(.|..)'
$ echo *
..two .one none zero
$ FIGNORE='n*'
$ echo *
. .. ..two .one zero
You can include dot files in a pattern by matching them explicitly.
$ unset FIGNORE
$ echo @(*|.[^.]*|..?*)
..two .one none zero
To have the expansion come out empty if the directory is empty, use the N
pattern matching option: ~(N)@(*|.[^.]*|..?*)
or ~(N:*|.[^.]*|..?*)
.
Zsh
Set the dot_glob
option.
% echo *
none zero
% setopt dot_glob
% echo *
..two .one none zero
.
and ..
are never matched, even if the pattern matches the leading .
explicitly.
% echo .*
..two .one
You can include dot files in a specific pattern with the D
glob qualifier.
% echo *(D)
..two .one none zero
Add the N
glob qualifier to make the expansion come out empty in an empty directory: *(DN)
.
Note: you may get filename expansion results in different orders
(e.g., none
followed by .one
followed by ..two
)
based on your settings of the LC_COLLATE
, LC_ALL
, and LANG
variables.
By default bash
doesn't glob dot-files, so to remove everything but hidden files in bash
, using rm
:
rm *
Sample output:
~/tmp$ ls -la
total 8
drwxrwxr-x 2 user user 4096 giu 11 20:00 .
drwxr-xr-x 21 user user 4096 giu 11 08:26 ..
-rw-rw-r-- 1 user user 0 giu 11 20:00 .1
-rw-rw-r-- 1 user user 0 giu 11 20:00 2
-rw-rw-r-- 1 user user 0 giu 11 20:00 3
-rw-rw-r-- 1 user user 0 giu 11 20:00 4
-rw-rw-r-- 1 user user 0 giu 11 20:00 5
~/test$ rm *
~/tmp$ ls -la
total 8
drwxrwxr-x 2 user user 4096 giu 11 20:00 .
drwxr-xr-x 21 user user 4096 giu 11 08:26 ..
-rw-rw-r-- 1 user user 0 giu 11 20:00 .1
To remove everything but .gitkeep
in bash
, enabling globbing for dot-files and using rm
:
shopt -s dotglob
rm !(.gitkeep)
Sample output:
~/tmp$ ls -la
total 8
drwxrwxr-x 2 user user 4096 giu 11 20:19 .
drwxr-xr-x 21 user user 4096 giu 11 08:26 ..
-rw-rw-r-- 1 user user 0 giu 11 20:19 1
-rw-rw-r-- 1 user user 0 giu 11 20:19 2
-rw-rw-r-- 1 user user 0 giu 11 20:19 3
-rw-rw-r-- 1 user user 0 giu 11 20:19 4
-rw-rw-r-- 1 user user 0 giu 11 20:19 5
-rw-rw-r-- 1 user user 0 giu 11 20:19 .gitkeep
-rw-rw-r-- 1 user user 0 giu 11 20:19 .hidden
~/tmp$ shopt -s dotglob
~/tmp$ rm !(.gitkeep)
rm: cannot remove ‘.’: Is a directory
rm: cannot remove ‘..’: Is a directory
user@user-X550CL:~/tmp$ ls -la
total 8
drwxrwxr-x 2 user user 4096 giu 11 20:20 .
drwxr-xr-x 21 user user 4096 giu 11 08:26 ..
-rw-rw-r-- 1 user user 0 giu 11 20:19 .gitkeep
Best Answer
If you want the contents of a single directory, an easy method is to change to it first:
What you saw is that
*
expands to the list of names of files that don't begin with a.
. That's the documented behavior, and it's the main reason why files whose name begins with a.
are said to be hidden (the other is thatls
doesn't show them by default).There's no really convenient portable way to list all files in a directory. You can use
but if there is no file matching one of the patterns then the pattern will remain unexpanded. In bash, you can set the
dotglob
option to avoid treating a leading.
specially (.
and..
are still excluded from the matches):In ksh, or in bash if you set the
extglob
option (or in zsh if you set theksh_glob
option), you can write a pattern that matches all files except.
and..
:In zsh, there's a simpler way of saying that
.
must not be treated specially in a pattern: