4

Linux and Unix-like shells like bash allow for the use of globs to approximate filenames and make file searching easier. I'm aware of the wildcard glob (*). What other globs exist in bash that I can make use of with grep?

Hashim Aziz
  • 12,732
  • 3
    grep uses regular expressions; these are different than globs. Some grep implementations use globs with options like --exclude=GLOB but I think these options are not required by POSIX. So you shouldn't assume grep knows anything about globs. – Kamil Maciorowski Sep 18 '18 at 22:09
  • @KamilMaciorowski I'm aware of the difference between globs and regex, but I was under the impression that GNU grep supports globs by default (even with grep -F) just like most other commands in bash. – Hashim Aziz Sep 18 '18 at 22:11
  • 4
    "just like most other commands in bash" – grep is not a "command in bash" but a separate executable that you can run without a shell, if you know how. You should carefully distinguish globs expanded by bash before grep (or any command invoked in a shell) even runs from globs, regular expressions or anything alike that is supported by the command itself. – Kamil Maciorowski Sep 18 '18 at 22:16
  • E.g. find . -name supports glob-like pattern matching. See what happens when you let the shell expand them. – Kamil Maciorowski Sep 18 '18 at 22:33
  • So you're saying that grep itself doesn't use globs, and so globs can't be used with it? Something like grep -f *.txt won't return text files, or grep Match* file.txt won't return Match1, Match2, Match3, etc? – Hashim Aziz Sep 18 '18 at 23:45
  • 3
    The shell will expand globs before passing them to grep in the argument list. Thus, grep -f *.txt will expand to something like grep -f file1.txt file2.txt file3.txt, and grep will interpret file1.txt as the file to read search patterns from, and file2.txt and file3.txt as files to search for those patterns. grep has no idea whatsoever that there was a glob pattern involved, it only knows that it got the strings "-f", "file1.txt", "file2.txt", and "file3.txt" as arguments. – Gordon Davisson Sep 19 '18 at 02:09
  • 3
    Invoke set -x (use set +x to revert this later). Then run grep -f *.txt 1>/dev/null 2>/dev/null (redirections are just to make the command itself silent). Whatever you see after + is the actual command. Try it in directories with 0, 1 or more matching files. You will see what arguments grep really gets. – Kamil Maciorowski Sep 19 '18 at 06:44

1 Answers1

1

There is a difference between the bash builtin parameter expansion called glob, and what grep can understand as a search input.

Typical glob use is the *, to expand to any string in it's place that matches the rest of the string. For example:

ls
# 1.txt 2.txt 3.txt
grep "search string" *.txt
# expands the star to match anything ending in .txt, so in this case is the same as:
grep "search string" 1.txt 2.txt 3.txt

This is all bash, and also works with echo for example (but since it's bash it doesn't work inside quotes). To your actual question, here is the glob manpage which also describes several other matchers you can use as a glob. To summarize (using ls for the sake of simplicity):

ls ?.txt # matches any single character
ls [0-9].txt # matches a single character from 0 to 9
ls [[:digit:]].txt # same as above
ls [0-9A-Za-z].txt # matches any alphanumeric character

See the manpage for a complete list plus some notable special cases like matching a . for example.

For there grep search string there are several forms of (semi)standard regex strings you can use, see for example -e, -E or -P in the man page and general regex help online for the supported syntaxes that are way to numerous to list here.

Leon S.
  • 144