### Example script to replace GREP_OPTIONS Source: https://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html This shell script is an example of how to set grep options via a script instead of the deprecated GREP_OPTIONS environment variable. It prepends $HOME/bin to PATH and creates an executable script that calls grep with --color=auto and --devices=skip. ```shell #! /bin/sh export PATH=/usr/bin exec grep --color=auto --devices=skip "$@" ``` -------------------------------- ### Example of early exit with grep -q Source: https://www.gnu.org/software/grep/manual/html_node/Performance.html Using grep -q allows the command to exit immediately after finding a match, which may cause the preceding process in a pipe to exit with a nonzero status. ```shell sed '/^...$/d' | grep -q X ``` -------------------------------- ### Use --label with grep and gzip Source: https://www.gnu.org/software/grep/manual/html_node/Output-Line-Prefix-Control.html Example of using the --label option to treat standard input as a file named 'foo' when searching through a gzipped file. ```bash gzip -cd foo.gz | grep --label=foo -H 'some pattern' ``` -------------------------------- ### Shell script using grep -m 1 with a regular file Source: https://www.gnu.org/software/grep/manual/html_node/General-Output-Control.html This example shows a while loop that repeatedly runs grep -m 1 'PATTERN' on a regular file, printing 'xxxx' after each match. It works because grep positions the input just after the last selected line, allowing the loop to resume. ```shell while grep -m 1 'PATTERN' do echo xxxx done < FILE ``` -------------------------------- ### grep with pattern variable and * Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Shows a potential problem when pattern or file names start with '-'. The command may behave unexpectedly. ```shell grep "$pattern" * ``` -------------------------------- ### Shell script using grep -m 1 with a pipe (probably will not work) Source: https://www.gnu.org/software/grep/manual/html_node/General-Output-Control.html This example shows the same loop but reading from a pipe instead of a regular file. It probably will not work because a pipe is not a regular file, so grep cannot reposition the input. ```shell # This probably will not work. cat FILE | while grep -m 1 'PATTERN' do echo xxxx done ``` -------------------------------- ### Search standard input and files using '-' Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Uses the special file name '-' to tell grep to read from standard input in addition to the named files. The example pipes the output of cat into grep and also searches /etc/motd. ```shell cat /etc/passwd | grep 'alain' - /etc/motd ``` -------------------------------- ### Example of back-reference performance impact Source: https://www.gnu.org/software/grep/manual/html_node/Performance.html This pattern uses back-references which trigger an inefficient backtracking algorithm, resulting in exponential worst-case performance. ```regex grep -E "^(.*)\1{14}(.*)\2{13}$" ``` -------------------------------- ### Using grep -zP with (?s) to match across newlines Source: https://www.gnu.org/software/grep/manual/html_node/grep-Programs.html This example shows how to use the -z (--null-data) option with -P (--perl-regexp) and the (?s) directive to make the dot match line breaks. The command prints the input lines 'a' and 'b' as output. Note that with -z and a file containing no NUL byte, grep must read the entire file into memory, which can exhaust memory for large files. ```shell $ printf 'a\nb\n' |grep -zP '(?s)a.b' a b ``` -------------------------------- ### Example of cascaded repetition Source: https://www.gnu.org/software/grep/manual/html_node/Performance.html This pattern demonstrates a cascaded repetition that can cause stack overflow and is not portable under POSIX. ```regex grep -E ".*{10,}{10,}{10,}{10,}{10,}" ``` -------------------------------- ### Basic grep with -i and pattern 'hello.*world' Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Lists lines in menu.h and main.c containing 'hello' followed by 'world', ignoring case with -i. ```shell grep -i 'hello.*world' menu.h main.c ``` -------------------------------- ### grep -r with --include for C files Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Searches recursively for 'hello' in files matching '*.c' under /home/gigi, similar to the find command. ```shell grep -r --include='*.c' 'hello' /home/gigi ``` -------------------------------- ### grep with -- before pattern and files Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Alternative to -e and './' to handle leading '-'. Note that a file named '-' is misinterpreted as standard input. ```shell grep -- "$pattern" * ``` -------------------------------- ### Bash ANSI-C quoting with ASCII escape Source: https://www.gnu.org/software/grep/manual/html_node/Matching-Non_002dASCII.html Shows that using ANSI-C quoting for printable ASCII characters is equivalent to the literal character, which can lead to unintended matching. For example, this matches any line, not just lines containing '^'. ```shell grep $'\u005E' ``` -------------------------------- ### Output of grep 'eli' /etc/passwd /dev/null Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Shows the output of the previous command, including the file name and matching line. ```shell /etc/passwd:eli:x:2098:1000:Eli Smith:/home/eli:/bin/bash ``` -------------------------------- ### grep command line synopsis Source: https://www.gnu.org/software/grep/manual/html_node/Invoking.html Shows the general syntax for invoking grep. Options and file arguments are optional; patterns can be provided directly or via -e or -f options. Patterns should typically be quoted in shell commands. ```bash grep [option]... [patterns] [file]... ``` -------------------------------- ### List matching file names with grep -l Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Lists names of test-*.c files in the current directory whose contents mention 'main'. ```shell grep -l 'main' test-*.c ``` -------------------------------- ### Context output with grep -C 2 Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Prints two lines of context around each matching line. ```shell grep -C 2 'hello' test*.log ``` -------------------------------- ### Recursive search with grep -r Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Searches for 'hello' in all files under /home/gigi. ```shell grep -r 'hello' /home/gigi ``` -------------------------------- ### Search only C files using find and grep Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Uses find to locate C files and grep -H to search for 'hello' in them. The -exec ... + form passes multiple files to grep. ```shell find /home/gigi -name '*.c' ! -type d \ -exec grep -H 'hello' '{}' + ``` -------------------------------- ### Word-ending search with grep 'hello\>' Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Searches for words ending in 'hello', matching 'Othello'. ```shell grep 'hello\>' test*.log ``` -------------------------------- ### grep with -e and leading ./ for safety Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Avoids problems with leading '-' in patterns and file names by using -e for the pattern and './' for files. ```shell grep -e "$pattern" ./* ``` -------------------------------- ### Back-reference with no referent Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html This command produces an error because the second '\1' has nothing to refer back to, so it will never match anything. ```shell echo 'ba' | grep -E '(a)\1|b\1' ``` -------------------------------- ### grep with -n, --, and /dev/null for file names Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Outputs line numbers and file names for lines containing 'f' and ending in '.c' in files matching *g*.h. The -- treats later arguments as file names, and /dev/null forces file name output. ```shell grep -n -- 'f.*\.c$' *g*.h /dev/null ``` -------------------------------- ### Whole-word search with grep -w Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Searches for 'hello' as a whole word, not matching 'Othello'. ```shell grep -w 'hello' test*.log ``` -------------------------------- ### Match across lines with -z and -q Source: https://www.gnu.org/software/grep/manual/html_node/Usage.html Uses the -z (--null-data) option to treat input as null-terminated lines, allowing newlines to be matched. The -q option suppresses output, which is often combined with -z because a match typically outputs the entire input. ```shell printf 'foo\nbar\n' | grep -z -q 'foo[[:space:]]\+bar' ```