ls -d .* lists only hidden "items" (files & directories). (I think) technically it lists every item beginning with ., which includes the current . and above .. directories.

I also know that ls -A lists "almost all" of the items, listing both hidden and un-hidden items, but excluding . and ... However, combining these as ls -dA .* doesn't list "almost all" of my hidden items.

How can I exclude . and .. when listing hidden items?

  • maybe ls -d +(.)+([^.]) (you need extglob set)
    – user986805
    May 28, 2020 at 9:52
  • This works... how? May 28, 2020 at 9:54
  • 1
    +(.) match one or more dot follow by +([^.]) one or more non dots, it will match ... and so on ... you could optimize some more
    – user986805
    May 28, 2020 at 9:56
  • @jonnybolton16 that is a regex regex101.com very handy ;)
    – Rinzwind
    May 28, 2020 at 9:56
  • 2
    @bac0n Consider posting that as an answer.
    – Kulfy
    May 28, 2020 at 10:04

3 Answers 3


From the second answer in:

This works on my machine (I'm not using SSH like the OP though):

ls -d .!(|.)

If there are no hidden files or directories you will get an error message:

$ ls -d .!(|.)
ls: cannot access '.!(|.)': No such file or directory

The error message occurs on directories with no hidden files because . and .. are excluded.

shopt consideration

From comments:

ls -d .[!.]* works without extglob

  • Great! This works on my own machine and my work machine. But strangely it doesn't work on the gateway machine - I get the message -bash: syntax error near unexpected token `('. It's not a big deal, but it would be nice for it to work there too May 28, 2020 at 11:20
  • @jonnybolton16 I wonder what bash --version returns on each of the three machines? Perhaps that might be a clue. Other than that run diff command on results of shopt output from different machines my give the reason. May 28, 2020 at 11:26
  • 4.2.46(2) for work machine, 4.4.20(1) for local machine and 4.1.2(1) for gateway. From shopt I can see that the gateway has extglob off. This could be the issue. Doing shopt -s extglob made it work; though I could have sworn I did that earlier May 28, 2020 at 11:55
  • ls -d .[!.]* works without extglob May 28, 2020 at 12:01
  • 1
    I updated the answer from my phone to briefly reflect your new discoveries. May 28, 2020 at 12:32

You can use any set of options, and search the output stream for a matching string or not a matching string using grep.

From grep man page:

   grep  searches the named input FILEs (or standard input if no files are
   named, or if a single hyphen-minus (-) is given as file name) for lines
   containing  a  match to the given PATTERN.  By default, grep prints the
   matching lines.

So for example if my ls -A output is:

   . .. Desktop Documents Downloads

My ls -A |grep "Do" would be:


I can also use invert search using -v to search for anything that is not my expressions.

From grep man page:

-v, --invert-match select non-matching lines

So in your case the expression would be: ls -d .* |grep "[.][a-z]\|[0-9]"

  • No, this doesn't work... it returns empty May 28, 2020 at 9:58
  • sorry, I had an extra " at the end of my command - updated the line
    – Pizza
    May 28, 2020 at 9:59
  • 1
    I didn't include the extra " (I didn't even see it lol). The command ls -d | grep -v "[.]\|[..]" doesn't work May 28, 2020 at 10:05
  • 1
    You are correct, you can just use this, without -v: ls -d .* |grep "[.][a-z]"
    – Pizza
    May 28, 2020 at 10:17
  • Overall the best practice is to find something that is shortest to write and manipulate, but also that works. I tried that in my terminal this time and it works. Will edit my answer in accordance.
    – Pizza
    May 28, 2020 at 10:18

You can use also find:

find . -maxdepth 1 -type f -name '.*'

which prints out full path, or:

find . -maxdepth 1 -type f -name '.*' -printf "%f\n"

This works also for empty directories / no such files.

  • this will not find directories.
    – user986805
    May 28, 2020 at 13:28

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