Linux grep how to use

Что такое grep и с чем его едят

Эта заметка навеяна мелькавшими последнее время на хабре постами двух тематик — «интересные команды unix» и «как я подбирал программиста». И описываемые там команды, конечно, местами интересные, но редко практически полезные, а выясняется, что реально полезным инструментарием мы пользоваться и не умеем.
Небольшое лирическое отступление:
Года три назад меня попросили провести собеседование с претендентами на должность unix-сисадмина. На двух крупнейших на тот момент фриланс-биржах на вакансию откликнулись восемь претендентов, двое из которых входили в ТОП-5 рейтинга этих бирж. Я никогда не требую от админов знания наизусть конфигов и считаю, что нужный софт всегда освоится, если есть желание читать, логика в действиях и умение правильно пользоваться инструментарием системы. Посему для начала претендентам были даны две задачки, примерно такого плана:
— поместить задание в крон, которое будет выполняться в каждый чётный час и в 3 часа;
— распечатать из файла /var/run/dmesg.boot информацию о процессоре.

К моему удивлению никто из претендентов с обоими вопросами не справился. Двое, в принципе, не знали о существовании grep.

image

Поэтому… Лето… Пятница… Перед шашлыками немного поговорим о grep.

Зная местную публику и дабы не возникало излишних инсинуаций сообщаю, что всё нижеизложенное справедливо для

# grep --version | grep grep grep (GNU grep) 2.5.1-FreeBSD 
# man grep | grep -iB 2 freebsd -P, --perl-regexp Interpret PATTERN as a Perl regular expression. This option is not supported in FreeBSD. 

Для начала о том как мы обычно grep’аем файлы.
Используя cat:

root@nm3:/ # cat /var/run/dmesg.boot | grep CPU: CPU: Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz (2833.07-MHz K8-class CPU) 
root@nm3:/ # grep CPU: /var/run/dmesg.boot CPU: Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz (2833.07-MHz K8-class CPU) 
root@nm3:/ # grep WARNING /var/run/dmesg.boot | wc -l 3 
root@nm3:/ # grep WARNING /var/run/dmesg.boot -c 3 
root@nm3:/ # grep ".*" test.txt one two three seven eight one eight three thirteen fourteen fifteen sixteen seventeen eighteen seven sixteen seventeen eighteen twenty seven one 504 one one 503 one one 504 one one 504 one #comment UP twentyseven #comment down twenty1 twenty3 twenty5 twenty7 
root@nm3:/ # grep -w 'seven' test.txt seven eight one eight three sixteen seventeen eighteen seven twenty seven 
root@nm3:/ # grep '\' test.txt seven eight one eight three sixteen seventeen eighteen seven twenty seven twentyseven 
root@nm3:/ # grep '^seven' test.txt seven eight one eight three root@nm3:/ # grep 'seven$' test.txt sixteen seventeen eighteen seven twenty seven twentyseven root@nm3:/ # 
root@nm3:/ # grep -C 1 twentyseven test.txt #comment UP twentyseven #comment down 
root@nm3:/ # grep -A 1 twentyseven test.txt twentyseven #comment down root@nm3:/ # grep -B 1 twentyseven test.txt #comment UP twentyseven 
root@nm3:/ # grep "twenty4" test.txt twenty1 twenty3 
root@nm3:/ # grep "twenty[^1-4]" test.txt twenty seven twentyseven twenty5 twenty7 

Разумеется grep поддерживает и прочие базовые квантификаторы, метасимволы и другие прелести регулярок
Пару практических примеров:

root@nm3:/ # cat /etc/resolv.conf #options edns0 #nameserver 127.0.0.1 nameserver 8.8.8.8 nameserver 77.88.8.8 nameserver 8.8.4.4 
root@nm3:/ # grep -E "1\.6\.6\.7" /etc/resolv.conf #nameserver 127.0.0.1 nameserver 8.8.8.8 nameserver 77.88.8.8 nameserver 8.8.4.4 
root@nm3:/ # grep -E '\b8(\.8)\b' /etc/resolv.conf #nameserver 127.0.0.1 nameserver 8.8.8.8 nameserver 77.88.8.8 nameserver 8.8.4.4 
root@nm3:/ # grep -E '\b8(\.5)\b' /etc/resolv.conf | grep -v '#' nameserver 8.8.8.8 nameserver 77.88.8.8 nameserver 8.8.4.4 
root@nm3:/ # grep -oE '\b6(\.2)\b' /etc/resolv.conf | grep -v '#' 127.0.0.1 8.8.8.8 77.88.8.8 8.8.4.4 

Вот незадача… Закомментированная строка вернулась. Это связано с особенностью обработки шаблонов. Как быть? Вот так:

root@nm3:/ # grep -v '#' /etc/resolv.conf | grep -oE '\b6(\.2)\b' 8.8.8.8 77.88.8.8 8.8.4.4 

Здесь остановимся на инвертировании поиска ключом -v
Допустим нам нужно выполнить «ps -afx | grep ttyv»

root@nm3:/ # ps -afx | grep ttyv 1269 v1 Is+ 0:00.00 /usr/libexec/getty Pc ttyv1 1270 v2 Is+ 0:00.00 /usr/libexec/getty Pc ttyv2 1271 v3 Is+ 0:00.00 /usr/libexec/getty Pc ttyv3 1272 v4 Is+ 0:00.00 /usr/libexec/getty Pc ttyv4 1273 v5 Is+ 0:00.00 /usr/libexec/getty Pc ttyv5 1274 v6 Is+ 0:00.00 /usr/libexec/getty Pc ttyv6 1275 v7 Is+ 0:00.00 /usr/libexec/getty Pc ttyv7 48798 2 S+ 0:00.00 grep ttyv 
root@nm3:/ # ps -afx | grep ttyv | grep -v grep 1269 v1 Is+ 0:00.00 /usr/libexec/getty Pc ttyv1 1270 v2 Is+ 0:00.00 /usr/libexec/getty Pc ttyv2 1271 v3 Is+ 0:00.00 /usr/libexec/getty Pc ttyv3 1272 v4 Is+ 0:00.00 /usr/libexec/getty Pc ttyv4 1273 v5 Is+ 0:00.00 /usr/libexec/getty Pc ttyv5 1274 v6 Is+ 0:00.00 /usr/libexec/getty Pc ttyv6 1275 v7 Is+ 0:00.00 /usr/libexec/getty Pc ttyv7 
root@nm3:/ # ps -afx | grep "[t]tyv" 1269 v1 Is+ 0:00.00 /usr/libexec/getty Pc ttyv1 1270 v2 Is+ 0:00.00 /usr/libexec/getty Pc ttyv2 1271 v3 Is+ 0:00.00 /usr/libexec/getty Pc ttyv3 1272 v4 Is+ 0:00.00 /usr/libexec/getty Pc ttyv4 1273 v5 Is+ 0:00.00 /usr/libexec/getty Pc ttyv5 1274 v6 Is+ 0:00.00 /usr/libexec/getty Pc ttyv6 1275 v7 Is+ 0:00.00 /usr/libexec/getty Pc ttyv7 
root@nm3:/ # vmstat -z | grep -E "(sock|ITEM)" ITEM SIZE LIMIT USED FREE REQ FAIL SLEEP socket: 696, 130295, 30, 65, 43764, 0, 0 
root@nm3:/ # vmstat -z | grep "sock\|ITEM" ITEM SIZE LIMIT USED FREE REQ FAIL SLEEP socket: 696, 130295, 30, 65, 43825, 0, 0 

Ну и если об использовании регулярок в grep’e помнят многие, то об использовании POSIX классов как-то забывают, а это тоже иногда удобно.

Читайте также:  Making linux install usb

[:alpha:] Any alphabetical character, regardless of case
[:digit:] Any numerical character
[:alnum:] Any alphabetical or numerical character
[:blank:] Space or tab characters
[:xdigit:] Hexadecimal characters; any number or A–F or a–f
[:punct:] Any punctuation symbol
[:print:] Any printable character (not control characters)
[:space:] Any whitespace character
[:graph:] Exclude whitespace characters
[:upper:] Any uppercase letter
[:lower:] Any lowercase letter
[:cntrl:] Control characters

root@nm3:/ # grep "[[:upper:]]" test.txt #comment UP 

image

Плохо видно что нашли? Подсветим:

Ну и ещё пару трюков для затравки.
Первый скорее академичный. За лет 15 ни разу его не использовал:
Нужно из нашего тестового файла выбрать строки содержащие six или seven или eight:
Пока всё просто:

root@nm3:/ # grep -E "(six|seven|eight)" test.txt seven eight one eight three sixteen seventeen eighteen seven sixteen seventeen eighteen twenty seven twentyseven 

А теперь только те строки в которых six или seven или eight встречаются несколько раз. Эта фишка именуется Backreferences

root@nm3:/ # grep -E "(six|seven|eight).*\1" test.txt seven eight one eight three sixteen seventeen eighteen seven 

Ну и второй трюк, куда более полезный. Необходимо вывести строки в которых 504 с обеих сторон ограничено табуляцией.
Ох как тут не хватает поддержки PCRE…
Использование POSIX-классов не спасает:

root@nm3:/ # grep "[[:blank:]]504[[:blank:]]" test.txt one 504 one one 504 one one 504 one 
root@nm3:/ # grep " 504 " test.txt one 504 one 

Что ещё не сказал? Разумеется, grep умеет искать в файлах/каталогах и, разумеется, рекурсивно. Найдём в исходниках код, где разрешается использование Intel’ом сторонних SFP-шек. Как пишется allow_unsupported_sfp или unsupported_allow_sfp не помню. Ну да и ладно — это проблемы grep’а:

root@nm3:/ # grep -rni allow /usr/src/sys/dev/ | grep unsupp /usr/src/sys/dev/ixgbe/README:75:of unsupported modules by setting the static variable 'allow_unsupported_sfp' /usr/src/sys/dev/ixgbe/ixgbe.c:322:static int allow_unsupported_sfp = TRUE; /usr/src/sys/dev/ixgbe/ixgbe.c:323:TUNABLE_INT("hw.ixgbe.unsupported_sfp", &allow_unsupported_sfp); /usr/src/sys/dev/ixgbe/ixgbe.c:542: hw->allow_unsupported_sfp = allow_unsupported_sfp; /usr/src/sys/dev/ixgbe/ixgbe_type.h:3249: bool allow_unsupported_sfp; /usr/src/sys/dev/ixgbe/ixgbe_phy.c:1228: if (hw->allow_unsupported_sfp == TRUE)  

Надеюсь не утомил. И это была только вершина айсберга grep. Приятного Вам чтения, а мне аппетита на шашлыках!
Ну и удачного Вам grep'a!

Источник

Grep Command in Linux – Usage, Options, and Syntax Examples

Zaira Hira

Zaira Hira

Grep Command in Linux – Usage, Options, and Syntax Examples

Grep is a useful command to search for matching patterns in a file. grep is short for "global regular expression print".

If you are a system admin who needs to scrape through log files or a developer trying to find certain occurrences in the code file, then grep is a powerful command to use.

In this article, we will discuss the grep command's syntax and its usage with some examples.

Syntax of the grep Command

The syntax of the grep command is as follows:

image-73

How to Ignore Case Distinctions using -i

We can command grep to return results while ignoring the case of the matching string. Let's find the word "berries" from our sample file. It should match all occurrences of "berries" regardless of their case.

image-74

How to Select the Non-Matching Lines using -v

We can reverse the results of the grep command to include non-matching results. Let's say, if we want to get all the lines that do not contain the word "berries", the command would look like this:

image-75

The output returned all the lines that do not contain "berries".

How to Find the Line Numbers Against Matching Input using -n

There are times when we want to get the line numbers against the matching string. For that, we can supply the -n flag to grep like this:

image-76

From the output, we can see that the word "berries" occurs on line #5 of the file.

How to Find the Exact Matching Word from the Input File or String using -w

If you were to match an exact word rather than just the occurrence of a pattern, you can do so by using the -w flag.

If we grep "fruit" without any flags, it would return any occurrence of the word "fruit". This would include occurrences like "grapefruit", "dragonfruit" and so on like this:

image-77

But, if we only want "fruit" in our results, we can use the -w flag like this:

image-78

Do you see the difference? The latter result returned only one line where the exact word "fruit" was found.

How to Count the Number of Occurrences of the Provided Pattern using -c

We can count the number of times the matched string appears in the file. This is how the -c flag works:

image-79

The word "fruit" appears 3 times in the file.

Tip: The -c flag can be very useful if you have to count the number of times an error message appeared in a log file.

How to Scan Files for Matching Input

Until now we had discussed how to search for matching patterns in a file or input string. We can also use grep to narrow down the files that contain a matching pattern. We can use the following flags to separate files that contain the matching pattern:

  • -l, --files-with-matches : Prints the file name that contains the provided matching pattern.
  • -L, --files-without-match : Prints the file name that does not contain the provided matching pattern.

Let's say we have the following files in our folder:

zaira@Zaira:~/grep-tutorial$ ls -lrt total 12 -rw-r--r-- 1 zaira zaira 327 Jan 16 19:25 fruits.txt -rw-r--r-- 1 zaira zaira 47 Jan 16 20:31 vegetables.txt -rw-r--r-- 1 zaira zaira 194 Jan 16 20:33 more-fruits.txt

The files have the following content:

zaira@Zaira:~/grep-tutorial$ cat fruits.txt apples and pears citrus – oranges, grapefruits, mandarins and limes stone fruit – nectarines, apricots, peaches and plums tropical and exotic – bananas and mangoes berries – strawBERRIES, raspberries, blueberries, kiwifruit and passionfruit melons – watermelons, rockmelons and honeydew melons tomatoes and avocados.
zaira@Zaira:~/grep-tutorial$ cat more-fruits.txt passionfruit dragon fruit kiwis pears grapefruits, mandarins and limes stone fruit – nectarines, apricots, peaches and plums tropical and exotic – bananas and mangoes tomatoes and avocados.
zaira@Zaira:~/grep-tutorial$ cat vegetables.txt # Vegetables only Cabbage Onion Carrot Potato

Next, we want to see files that contain the pattern "fruit". We can do that like this:

Note that the * searches for all the files in the folder.

zaira@Zaira:~/grep-tutorial$ grep -l "fruit" * fruits.txt more-fruits.txt

Let's say we want to list files that do not contain the word "fruit". We can achieve that using the command below:

zaira@Zaira:~/grep-tutorial$ grep -L "fruit" * vegetables.txt

Wrapping Up

If you want to study the grep command in depth, have a look at the man pages. You can get additional information on the command line with grep --help .

I hope you found this tutorial helpful!

What’s your favorite thing you learned from this tutorial? Let me know on Twitter!

You can read my other posts here.

Источник

Оцените статью
Adblock
detector