

So I encourage those who haven't read them yet to do so, either before or after reading the rest of this answer.Īssuming the * does make it to grep-which quoting should ensure- grep then takes it to mean that the item that precedes it may occur any number of times, rather than having to occur exactly once. The other answers-such as those by Sergiy Kolodyazhnyy and by kos-also address this aspect of this question, in somewhat different ways. Then the grep command treats * as a quantifier. Quote your regular expression and the problem goes away. A grep command with an unquoted pattern that works now may stop working when you have different files or when you run it from a different place. You can sometimes rely on #2 and #3 but you can rarely rely on #1. In Bash that would have been done by enabling the nullglob or failglob shell option, respectively. You have not otherwise told your shell to allow globs to be replaced with nothing when there are no matching files, nor to fail with an error message in this situation. Or you have changed this behavior of your shell-how that is done varies across shells. (The default behavior in the popular shell Zsh, for instance, is for globs to either (a) expand or (b) produce an error.). This is the case in Bash, which you are probably using, but not in all Bourne-style shells. You are using a shell whose default behavior is to leave * alone when there are no matching filenames. But this is uncommon and you would probably know you did it. There were no files whose names matched.Or you have disabled globbing in your shell, typically with set -f or the equivalent set -o noglob. The reason this is sometimes not a problem-and in your particular case, at least so far, it wasn't-is that * will be left alone if all of the following are true:

(You do not see the list-it is passed opaquely to grep.) You virtually never want this to happen. The effect with grep will usually be that the first matching filename is taken as the regular expression-even if it would be quite obvious to a human reader that it is not meant as a regular expression-while all the other filenames listed automatically from your glob are taken as the files inside which to search for matches. or you've configured your shell to include them anyway.) This is known as globbing-and also by the names filename expansion and pathname expansion. are excluded-unless your pattern itself starts with. When the shell encounters a * character that is not quoted, it takes it to mean "zero or more of any character" and replaces the word that contains it with a list of filenames that match the pattern. You should always quote regular expressions for grep-and single quotes are usually best- unless you are sure you are okay with the nine types of potentially surprising transformations the shell otherwise performs before executing the grep command. For patterns that contain the directory separator /, it may depend on what files exist across your whole system. That depends on what files exist in whatever directory you happen to be in when you run the command. Whether the expression is enclosed in quotes makes no difference. Although sort of similar conceptually, what * means to the shell is quite different from what it means to grep. You must take both into account, though if you quote your regular expression then you can prevent the shell from treating it specially and ensure that it passes it unchanged to grep. * has a special meaning both as a shell globbing character ("wildcard") and as a regular expression metacharacter. This may not be the desired behavior in case it's not, you can turn on grep's PCRE engine (using the -P option) and append the ? metacharacter, which when put after the * and + metacharacters has the effect of changing their greediness: % cat infileġ: Basic Regular Expressions, Extended Regular Expressions and Perl Compatible Regular Expressions it will match the longest match: % cat infile The * metacharacter in BREs and EREs is always "greedy", i.e. metacharacter, which matches any character: % cat infile

To match 0 or more occurences of any character, you want to match 0 or more occurences of the. This means that in the This*String pattern, being the * metacharacter not preceded either by a grouped pattern or a character class, the * metacharacter matches 0 or more occurences of the previous character (in this case the s character): % cat infile The * metacharacter in BRE 1s, ERE 1s and PCRE 1s matches 0 or more occurences of the previously grouped pattern (if a grouped pattern is preceding the * metacharacter), 0 or more occurences of the previous character class (if a character class is preceding the * metacharacter) or 0 or more occurences of the previous character (if neither a grouped pattern nor a character class is preceding the * metacharacter)
