6

My goal is to find all files or directories in a filesystem that start with a dot (.), for example .gnupg. So I came up with the command:

find -name '.*'

Checking on the Internet, I saw some hints saying that I should use [.]* instead as the parameter value for -name option. What is the difference between both approach, since the result looks like the same?

3 Answers 3

6

There's no difference at all. If you try:

$ diff <(find -name '.*') <(find -name '[.]*')

you get no output. This means that command outputs are identical. I think you're taking that "hint" out of context. The intent was probably something different.

From the find man page:

-name pattern
Base of file name (the path with the leading directories removed) matches shell pattern pattern. The metacharacters (*',?', and []') match a.' at the start of the base name (this is a change in findutils-4.2.2)

meaning that [] in the -name argument is construed as a character class. With nothing but . in it, it matches a literal . as if you didn't use the [].

4
  • The command you show is not proving anything
    – Bernhard
    Oct 23, 2013 at 21:31
  • @Bernhard Please elaborate.
    – Joseph R.
    Oct 23, 2013 at 21:38
  • One example can not be used as a proof. Only a counter-example can be used to disproof something.
    – Bernhard
    Oct 23, 2013 at 21:43
  • 1
    @Bernhard Fair enough. Does the edit help?
    – Joseph R.
    Oct 23, 2013 at 22:49
0

For a glob pattern, there is no difference. .* is a literal period followed by zero or more characters. [.]* is any one character inside the brackets--in this case, it has to be a literal period--followed by zero or more characters.

The similar looking regular expressions .* and [.]* are different. The first is zero or more occurrences of any single character, while the second is zero or more occurrences of a literal period. The . is a regular expression metacharacter, but not inside square brackets, where it is treated literally.

2
  • Except that, when using -name, . (outside a character class) is also a literal character not a regex metacharacter.
    – Joseph R.
    Oct 25, 2013 at 0:36
  • Yes. Based on the original question, it looked like the OP was reading advice meant for regular expressions, which is why I brought them up.
    – chepner
    Oct 25, 2013 at 1:09
-1

How about

'\.[a-z]*'

The expression expects a literal dot followed by any amount of alphabetic characters. It seemed to work for me in a quick test. You need the backslash to escapes the dot. It's usually a meta-character signifying "any character" (more or less).

My whole expression was

find ~/ -name '\.[a-z]*'

Edit: To include dot-files starting with numbers too, try '\.[a-z0-9]*'. I'm not quite sure why you can't just say '\.(.*)', but I'm sure someone has a suggestion.

2
  • All "."s are literal in a find pattern. It's not a meta-character unless you use -regex instead of -name.
    – jordanm
    Oct 23, 2013 at 21:16
  • You're confusing the shell wildcard pattern syntax also used by find -name with the regex syntax of grep, sed, etc., also used by find -regex. Oct 23, 2013 at 23:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .