Что такое grep и с чем его едят
Эта заметка навеяна мелькавшими последнее время на хабре постами двух тематик — «интересные команды unix» и «как я подбирал программиста». И описываемые там команды, конечно, местами интересные, но редко практически полезные, а выясняется, что реально полезным инструментарием мы пользоваться и не умеем.Небольшое лирическое отступление: Года три назад меня попросили провести собеседование с претендентами на должность unix-сисадмина. На двух крупнейших на тот момент фриланс-биржах на вакансию откликнулись восемь претендентов, двое из которых входили в ТОП-5 рейтинга этих бирж. Я никогда не требую от админов знания наизусть конфигов и считаю, что нужный софт всегда освоится, если есть желание читать, логика в действиях и умение правильно пользоваться инструментарием системы. Посему для начала претендентам было даны две задачки, примерно такого плана: — поместить задание в крон, которое будет выполняться в каждый чётный час и в 3 часа; — распечатать из файла /var/run/dmesg.boot информацию о процессоре.К моему удивлению никто из претендентов с обеими вопросами не справился. Двое, в принципе, не знали о существовании grep.
Поэтому… Лето… Пятница… Перед шашлыками немного поговорим о 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® Core™2 Quad CPU Q9550 @ 2.83GHz (2833.07-MHz K8-class CPU) Но зачем? Ведь можно и так: root@nm3:/ # grep CPU: /var/run/dmesg.boot CPU: Intel® Core™2 Quad CPU Q9550 @ 2.83GHz (2833.07-MHz K8-class CPU) Или вот так (ненавижу такую конструкцию): root@nm3:/ #
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
И приступим к поискам: Опция -w позволяет искать по слову целиком:
root@nm3:/ # grep -w 'seven' test.txt
seven eight one eight three
sixteen seventeen eighteen seven
twenty seven
А если нужно по началу или концу слова?
root@nm3:/ # grep '\
Отберём строки с заглавными символами:
root@nm3:/ # grep »[[: upper:]]» test.txt
#comment UP
Плохо видно что нашли? Подсветим:
Ну и ещё пару трюков для затравки.Первый скорее академичный. За лет 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 На помощь приходит конструкция [CTRL+V][TAB]: 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!
