The rule for filename expansion have a special case for .
as the first character in a filename: it must be explicitly matched (i.e. the pattern must contain a starting .
, or .
after a /
). Otherwise these files are not candidates.
This is why your first version does pick up filenames that start with .
, but the second doesn't. *
doesn't match .
as the first character of a filename.
POSIX Shell Command Language describes it as:
If a filename begins with a period ( '.' ), the period shall be explicitly matched by using a period as the first character of the pattern or immediately following a slash character. The leading period shall not be matched by:
- The asterisk or question-mark special characters
- A bracket expression containing a non-matching list, such as "[!a]", a range expression, such as "[%-0]", or a character class expression, such as "[[:punct:]]"
It is unspecified whether an explicit period in a bracket expression matching list, such as "[.abc]", can match a leading period in a filename.
Your shell might have options to change this behavior. Bash has this for instance (Filename expansion):
When a pattern is used for filename expansion, the character ‘.’ at the start of a filename or immediately following a slash must be matched explicitly, unless the shell option dotglob is set. When matching a file name, the slash character must always be matched explicitly. In other cases, the ‘.’ character is not treated specially.
Note that these are not regular expressions. .*
as a regex would match anything at all (including nothing). *.
would be ill-formed.