Linux: работа с утилитой grep (egrep, zgrep, rgrep, etc)

  • У особо душных зачастую вызывает недоумение – зачем открывать через cat файл, который потом передается в grep. Отвечаю – часто ты открываешь сначала файл чтобы посмотреть в целом что там есть, а уже после первого просмотра передаешь в grep. У многих такой паттерн вошел в привычку – вот пример обучения по Linux LPIC-1 🙂 препод максимально опытный админстратор Linux (с начала 90х)

У grep 1001 alias, вот список из man. Причем эти alias обычно заменяются флагами самого grep:

  • fgrep = grep -F (fix string)
  • egrep = grep -E (regular expressions)
  • rgrep = grep -r (recursive)
grep, egrep, fgrep, rgrep, bzgrep, bzegrep, bzfgrep, zgrep, zegrep, zfgrep – file pattern searcher

–color=auto – посветка найденного текста

$ grep --color=auto 12 sw
123
123

-w/–word-regexp – удобная опция, ищем конкретное слово. Очень удобно, если есть уникальные слова в каждой строке (напр. ID).

 -w, --word-regexp
The expression is searched for as a word (as if surrounded by
`[[:<:]]' and `[[:>:]]'; see re_format(7)).

$ cat sw
1 -- xxx
2 -- yyy
3 -- zzz
4 -- kkk
5 -- zzz

$ cat sw | grep -w 2
2 -- yyy

$ cat sw | grep -w yyy
2 -- yyy

or/and

OR – ищем любой из двух. При любом подпадании из двух выводим, если попали оба – выводим оба результата.

grep 'INTEGER: 1\|INTEGER: 2' test

Аналоги с EGREP/GREP -E. На обучении lpi-1 писали [1,2,3] перечисляя независимые элементы, но запятая по факту не нужна, это отдельный от чисел независимый элемент.

$ grep -E 'INTEGER: 1|INTEGER: 2' test
$ grep -E 'INTEGER: [12]' test
$ grep -E 'INTEGER: [1-2]' test

no

grep –invert-match  (или grep -v) – делаем grep строк с значением НЕэталон

$ cat >sw
1
2
3

$ grep --invert-match 1 sw
2
3

recursive

Ищем во всех файлах (в содержимом) подпапки, не только в текущей; по умолчанию отображется как название файла, так и все вхождения по поиск, но если добавить флаг -l отображаются только название каждого файла, без сожержимого.

grep -r “limit” *
grep -lr “limit” *

Найти в файлах (в содержимом) всей директории pattern case insensitive (на все случаи). Не следует запускать его на корень (/) т.к. работать будет очень долго.

~$ grep -inr 'pattern' . >res

A/B (After match/Before match)

Можно посмотреть сколько то строк до вхождения (Before) и после (After).

-bash-4.2$ cat >test
1
2
3
4
5
6
7
8
9
-bash-4.2$ grep -B 2 -A 1 5 test
3
4
5
6

(grep, sed) grep from pattern to pattern / from pattern to end

решается с помощью sed

I want to "grep" from "line 2A" to the end of file:
sed -n '/2A/,$p'
sed -n '/sendconfig/,$p' /etc/failover.ini

I want to "grep" from "line 2A" to the next line that contains "A":
sed -n '/2A/,/A/p'
sed -n '/sendconfig/,/activeip/p' /etc/failover.ini

zgrep

Используется для поиска в архивированных файлах

rEGEXP

Что-то простое можно сделать через простой grep.

# диапазон
grep "Ищем [2-3] диапазон 2-3" test_file
# последний символ в строке
$ cat >sw
13129319fsdf1
fsdfri2m23irm2
#823478$*81!
fsdf2i3g!f
$ grep -o '.$' sw
1
2
!
f

Что-то более сложное уже потребует включения extended-regexp через grep -E или используя alias egrep:

grep -oE '\((.+)\)
    • -E – включение использования расширенных регулярных выражений в grep
    • -o – показываем только то, что подпало под regexp, а не всю строку, очень полезная вещь когда нужно что-то выделить, а остальное отбросить

 

questions

Which grep command will print only the lines that do not end with a / in the file foo?

A. grep’/$’ foo

B. grep ‘/#’ foo

C. grep -v ‘/$’ foo

D. grep -v ‘/#’ foo

Answer: C

 

 

Leave a Reply