Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to glob every hidden file and directory, but not the current (.) and parent directory (..).

I am using bash.

Observe current behaviour:

$ ls -a
.  ..  ...a  ...aa  ..a  ..aa  .a  .aa  .aaa  a
$ echo *
$ echo .*
. .. ...a ...aa ..a ..aa .a .aa .aaa

I would like .* to behave like this

$ echo .*
...a ...aa ..a ..aa .a .aa .aaa

There is the shell option dotglob

$ shopt -s dotglob

that works in a way; now I can use * to glob everything (hidden or not) but not . and ..

$ echo *
...a ...aa ..a ..aa .a .aa .aaa a

but now I can't differentiate between hidden or not. Also, .* still globs . and ..

$ echo .*
. .. ...a ...aa ..a ..aa .a .aa .aaa

Is there a way to make .* not expand to . and ..?

share|improve this question
Possible cross site duplicate of: stackoverflow.com/questions/2910049/… –  Ciro Santilli Mar 6 at 10:27

7 Answers 7

up vote 19 down vote accepted

You can use the GLOBIGNORE variable to hide the . and .. directories. This does automatically also set the dotglob option, so * now matches both hidden and non-hidden files. You can again manually unset dotglob, though, this then gives the behavior you want.

See this example:

$ ls -a
.  ..  a  .a  ..a
$ shopt -u dotglob
$ echo * # all (only non-hidden)
$ echo .* # all (only hidden)
.a ..a
share|improve this answer
This only works if you include the glob in the command; env GLOBIGNORE=". .." ls -a returns . and .. but ... ls -ad .* doesn't. –  gvkv Aug 24 '10 at 13:04
I don't get this comment... The question was not about the ls command, but about a glob -- "including the glob in the command" is exactly what the OP wanted to do... –  Marcel Stimberg Aug 24 '10 at 13:31
It's informational not critical. –  gvkv Aug 24 '10 at 13:48
No problem, I'm not afraid of criticism. It's just that I didn't understand the connection between the comment and my answer. But as I did also not understand your the connection between your answer and the original question that's consistent at least ;) –  Marcel Stimberg Aug 24 '10 at 13:55
Yeah, I got caught up with trying to make extended globbing patterns work with . the way I think it should using ls as a canonical command and forgot about the details of the post. –  gvkv Aug 24 '10 at 14:03

Are you just looking for files? Are you in a position to use find?

Something like:

find . -maxdepth 1 -name ".*" -f -printf "%P \n"
share|improve this answer

This glob requires a leading dot and at least one other non-dot character. This will glob any possible hidden files, but not . or .., which is exactly what you asked for.

ls -ld .[!.]*
share|improve this answer
That would also exclude ..foo. The portable syntax is .[!.]*. .[^.]* is not standard (though supported by many shells) –  Stéphane Chazelas Jan 9 at 10:20
@StephaneChazelas: Today I learned! Fixed. –  bukzor Mar 10 at 17:48
ls -1a|egrep -v '^(\.|\.\.)$'
share|improve this answer
ls should never be parsed or used in scripts, and certainly not as a replacement to globbing. –  MestreLion Mar 28 '13 at 7:19
Right, see mywiki.wooledge.org/ParsingLs for more information –  ignis Apr 25 '13 at 9:45

With zsh:

echo .*

(zsh globs never expand . or .., which is the most sensible thing to do).

With bash:

shopt -s dotglob
echo [.]*


echo .*

(with bash, as soon as GLOBIGNORE is non-empty, both . and .. are automatically ignored (and dotglob is enabled)).

With ksh93

echo .*
share|improve this answer

You want to show hidden files/folders BUT . and .. ?

Use this bash wildcard {.[!.]*,..?*}

Sample Data

You can try by generating sample data :

$ touch ...a  ...aa  ..a  ..aa  .a  .aa  .aaa  a
$ mkdir ...b  ...bb  ..b  ..bb  .b  .bb  .bbb  b


Below you can see the expected removed entries :

$ diff <(\ls -a) <(\ls -ad {.[!.]*,..?*})
< .
< ..
< a
< b


Useful to delete all hidden elements for example :

$ rm -rf .*
rm: cannot remove directory: `.'
rm: cannot remove directory: `..'

# <regenerate sample data here>

$ rm -rf {.[!.]*,..?*}
# No error
share|improve this answer

try ls -A.

excerpt from the manual

"-A, --almost-all do not list implied . and ..")

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.