Samples
File
Search a file.
$ grep foo file.txt
Equivalent of:
$ cat file.text | grep foo
Directory
Search recursively in current directory, case insensitively.
$ grep -ir PATTERN
Filename
Show the filename.
$ grep -H foobar *
foo.txt:This is foobar
bar.txt:This is another match for the foobar pattern
URLs
Find URLs in a JSON which is only one line.
Linux
This uses a pattern I came up with - note it doesn’t cover ? or trailing /.
$ grep -P -o 'https:\/\/[\w./?&=_#-]*' file.txt
https://docs.mongodb.com/manual/core/data-model-design/
https://www.oreilly.com/library/view/50-tips-and/9781449306779/ch01.html
https://leetcode.com/
Use -P for Perl regex (available in Linux only) so \w is treated as alphanumeric and not literal \w. Pattern must be in Perl regex syntax.
Using [[:alpha:]] might work too.
Without -P flag:
https://
https://www.
https://
Without -o flag, you see the entire line, but with the match patterns highlighted (assuming colors are enabled).
macOS
Using alphanumeric explicitly.
$ grep -o 'https:\/\/[a-zA-Z0-9./?&=_#-]*' file.txt
I could not get s? to work as optional for http / https.
Advanced path matching
Use the find command to filter the paths and then apply grep.
Here we look for files named index.md which do not contain the text foo. And only show each path once.
$ grep -L foo $(find . -type f -name index.md )
Search for a string starting with a dash
Say you are looking for flag -m.
You’ll get an error with:
$ grep -m
So use double dash to signal end of flags:
$ grep -- -m
Convert search results to an array
Grep will return results as a single multi-line string. This can be split into a Bash array like this.
$ MATCHES=($(grep -l -R needle .))
And the items (note index starts at one, not zero).
$ echo ${MATCHES[1]}
$ echo ${MATCHES[2]}
Use the -l flag to show paths of files and not the actual content matches.