7
  • * is roughly a wild card character with a unlimited amount of length.
  • ? is roughly a wild card character for one or zero length.

Is there a difference between using * vs ?* when searching for strings in bash?

  • 4
    In the context of globbing or regex? – llua Aug 7 '18 at 21:09
  • 1
    I think this is a globbing question, not a regular-expression question, in which case the tags should change; if it's about Bash regular expressions instead/as well then the text should change to say what it's really asking. It looks like the regular-expressions tag was added in someone's edit so I presume that's the wrong part. – Michael Homer Aug 8 '18 at 5:24
  • 1
    I've edited accordingly, but please revert & edit to say what you wanted if I got that wrong. There's confusion because "one or zero" is a regex thing, but ?* isn't a useful thing to write in a regular expression. – Michael Homer Aug 8 '18 at 5:27
  • Can you show an example of this "search for strings in bash"? It could be a incidentally bash while running grep with a regular expression, or find with a filename pattern, or as a wildcard. – Jeff Schaller Aug 8 '18 at 11:07
16

The difference is that in bash (as you tagged the question) * matches any string with length zero or more characters, while ?* matches a string with at least 1 character. Consider for example two files: file.txt and xfile.txt and try to list them with ls ?*file.txt or ls *file.txt.

One real case scenario when I use such construct is to list hidden files. Very often I just do

ls .??*

Double question marks are here to prevent listing the current directory . and the parent directory .., like it would be with a simpler form ls .*.


I need to point here that my .??* is not perfect; for example filenames with only two characters, like .f, don't match this pattern. More reliable solution is ls {..?,.[!.]}*, but usually that is too much to type for me.

  • find /home/?*/.[!.]?* -maxdepth 0 -perm /g+wx,o+rwx -exec chmod g-wx,o-rwx '{}' + – TrevorKS Aug 8 '18 at 1:34
  • That is the command the lead me to this question, same strategy taken to avoid the current and parent directories. – TrevorKS Aug 8 '18 at 1:35
  • 1
    Just an FYI, if you are using GNU coreutils (and you probably are), you can just pass -a to ls to see all files, or -A to see all files except . and ... – Jonathan Callen Aug 8 '18 at 7:31
  • @JonathanCallen Yes of course, but for other commands that's not always the case, like for example checking the size of dot-files du -scm .??* vs du -scm .*. – jimmij Aug 8 '18 at 13:17
  • .??* will also miss files like .x. Best would be to use a shell like pdksh, mksh, zsh or fish which never include . nor .. in their glob expansions. Or in ksh93, set FIGNORE to @(.|..) (though that has the side effect of no longer hiding dot-files). In other shells, you'll need .[!.]* .??* (or .[^.]* .??* in some shells, which excepts in csh/tcsh will likely give you an error (by ls) if either of the globs doesn't match (likely the first). – Stéphane Chazelas Feb 19 at 9:17
7

Where did you get that definition from, of to what kind of expression do you refer?

If we talk about shell expressions, both characters can be used alone, but the definition for ? doesn't match, as then it always matches one character and not one or zero.

If we talk about regular expressions, both are operators that are placed after an expression. So in "?*" would have to be placed after something else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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