How to use _one_ shell globbing expression to list all files (of course hidden files too!)?

Ok, this question targets Unix/Linux shells!

I want a shell globbing (aka wildcard) pattern or GLOBIGNORE list that matches all files, including hidden files, in the current directory non-recursively (maxdepth == 1). So far, I have to perform two commands or use long workarounds (see below):

ls -lad *vim*
ls -lad .*vim*

while using zsh. If I remember, it's the same for dash and bash, right?

Short workarounds:

ls -la | grep vim
find . -maxdepth 1 | grep vim

I've wondered a hundred times: isn't there a simple globbing solution to this? Why does * not match the dot character?


Solution 1:

* does match a . character.

It simply doesn't match . when it is the first character of the name. This provides a so-called "dot file" mechanism for "hiding" files.

In zsh:

Set the GLOB_DOTS shell option. This is in § 14.8 of the zsh user manual. Note that . and .. are always excluded even if this option is turned on.

In bash:

Set the dotglob shell option. This is in § 3.5.8 of the bash user manual. Note that setting the GLOBIGNORE shell variable implicitly sets dotglob; that bash (unlike zsh) doesn't automatically exclude . and .. when dotglob is enabled; but that bash will do that when GLOBIGNORE is set. So setting GLOBIGNORE=. will have the effect of turning on dotglob and excluding . and ...

In GNU find:

Don't do anything. As of findutils 4.2.2, the globbing for -name and -iname already matches names with dots as the first character. This is in § 2.1.1 of the findutils user manual.

Solution 2:

If you don't want to change any options, any of these will do:

ls -ld {,.}*vim*
ls -ld *vim* .*vim*
find . -maxdepth 1 -name "*vim*"

Solution 3:

In bash, enable the dotglob option:

shopt -s dotglob

By default, hidden files are hidden to not cause surprises and annoyances – for example, you run ls in your home directory, see some files from last month, try to remove them with rm *net* and unknowingly nuke your carefully written .nethackrc.

Solution 4:

In ZSH (without changing GLOB_DOTS) you could do

  ls -lad *vim*(D)

Solution 5:

To build on the answer of @daniel kullman, this seems to accomplish what you want with a fairly simple glob, even though it's not strictly a single gob.

Recursively search for the string "blah" in all files in the current directory, including hidden files, and excluding the ".." that causes the parent directory structure to be searched:

grep blah {,.}[!.]*