The shell executes the glob extension before it even comes up with a command call. Programs like grep do nothing to prevent swallowing: they cannot. You, as the caller from these programs, must tell the shell that you want to pass special characters to the program, such as * and ? , and prevent shell interpretation. You do this by putting them in quotation marks:
grep -E 'ba(na)* split' *.txt
(look for ba split , bana split , etc. in all files called <something> .txt ). In this case, single quotes or double quotes will do the trick. Between single quotes, the shell does not expand anything. Between the double quotes $ , ` and \ are still interpreted. You can also protect one character from shell expansion by preceding it with a backslash. These are not just wildcards that need to be protected; for example, above, the space in the template is in quotation marks, so it is part of the grep argument, not a separator of the arguments. Alternative ways of writing the above snippet include
grep -E "ba(na)* split" *.txt grep -E ba\(na\)\*\ split *.txt
In most shells, if the argument contains wildcards, but the pattern does not match any files, the pattern remains unchanged and is passed to the base command. So a team like
grep b[an]*a *.txt
has a different effect, depending on which files are present on the system. If the current directory does not contain a file whose name begins with b , the command looks for the pattern b[an]*a in files whose name matches *.txt . If the current directory contains files named baclava , bnm and hello.txt , the command expands to grep baclava bnm hello.txt , so it searches for the baclava template in the two bnm and hello.txt . Needless to say, it is a bad idea to rely on this in scripts; on the command line, it can sometimes save input, but it is dangerous.
When you run ack .* In a directory that does not contain a point file, the shell starts ack . .. ack . .. The behavior of the ack command is to print all non-empty lines (pattern.: Matches any one character) in all files under .. (the parent of the current directory) recursively. Contrast with ack '.*' , Which looks for the .* Pattern (which matches something) in the current directory and its subdirectories (due to ack behavior when you do not pass any file name argument).