rm -rf .*
will only not end horribly because rm
refuses to delete .
and ..
.
How do I exclude these special directories from a glob pattern?
This is not solved by dotglob
since I want to match only files beginning with a dot not all files.
rm -rf .*
will only not end horribly because rm
refuses to delete .
and ..
.
How do I exclude these special directories from a glob pattern?
This is not solved by dotglob
since I want to match only files beginning with a dot not all files.
With bash, setting the GLOBIGNORE
special variable is some non-empty value is enough to make it ignore .
and ..
when expanding globs. From the Bash docs:
The
GLOBIGNORE
shell variable may be used to restrict the set of filenames matching a pattern. IfGLOBIGNORE
is set, each matching filename that also matches one of the patterns inGLOBIGNORE
is removed from the list of matches. If thenocaseglob
option is set, the matching against the patterns inGLOBIGNORE
is performed without regard to case. The filenames.
and..
are always ignored whenGLOBIGNORE
is set and not null. However, settingGLOBIGNORE
to a non-null value has the effect of enabling the dotglob shell option, so all other filenames beginning with a‘.
’ will match.
If we set it to .:..
, both .
and ..
will be ignored. Since setting it to anything non-null will also get this behaviour, we might as well set it to just .
So:
GLOBIGNORE=.
rm -rf .*
(From my earlier answer on Ask Ubuntu.)
This should do it:
rm -rf .[^.] .??*
This command can catch all cases.
.[^.]
will catch any two character entries.
.??*
will only match 3+ character filenames.
@Goro has, I think, the simplest totally correct answer. However, I find it's a pain to type. I would suggest instead
ls .??*
It's absolutely true that this will miss files like .a
, but those are so extraordinarily rare that in practice I don't think it matters, especially for interactive usage.
You need to exclude single and double dots:
rm -rf {..?,.[!.]}*
..?*
matches everything with two dots followed by anything.[!.]*
matches everything with single dot not followed by another dotWith extglob
:
$ shopt -s extglob
$ touch ... .a .bbb ..c foo
$ echo .!(.|)
... .a .bbb ..c
!(.|)
matches anything but a dot or empty, so .!(.|)
matches anything starting with a dot, except .
and ..
.
With find
, it's a bit more to type but you can be more explicit, which makes it easier to understand:
find . -maxdepth 1 -name '.*' ! -name . ! -name .. -exec rm -rf {} +
This calls rm -rf
with all names in the current directory (only) that starts with a dot and which is not .
nor ..
. I'm not using -delete
here as that predicate may not delete non-empty directories.
If you want to match only regular files in the current directory, it becomes even easier:
find . -maxdepth 1 -type f -name '.*' -delete
Here, we don't need to exclude .
or ..
as they are automatically excluded by -type f
.
Change -type f
to ! -type d
to make it delete any non-directory (i.e. symbolic links etc.)
dotglob
? Here, they just want those starting with a dot. – ilkkachu Oct 18 '18 at 09:38