grep: примеры использования |
![]() |
Добавил(а) microsin |
Утилита grep применяется как универсальное средство для фильтрации строк текста по шаблону, возможно использование в качестве шаблона регулярных выражений. Есть также синонимы для этой команды - fgrep и egrep, причем egrep использует регулярные выражения, а grep и fgrep ничем не отличаются. Например, команда # grep gregor /etc/passwd выдаёт строку gregor:*:1001:1001:gregorlgn:/home/gregor:/bin/sh что говорит о том, что командный интерпретатор для пользователя gregor - sh. Строгий поиск. Пример строгого (опция w) поиска последовательности символов DEADBEEF по содержимому всех файлов в текущем каталоге и в его подкаталогах (опция r), с отображением номера строки, где встретилась эта последовательность (опция n). Строгий поиск означает, что будут выведены только те результаты, где указанная последовательность точно совпадает со словом, но не с частью слова: $ grep -rnw DEADBEEF Нестрогий поиск. Без опции w тот же пример выдаст результаты, где указанная последовательность совпадает как полностью со словом, так и с частью слова. Таким образом, будут выведены также результаты совпадений, где содержится, к примеру, слово 0xDEADBEEF: $ grep -rn DEADBEEF Опция l. Указать только имена файлов без результатов совпадения можно, если указать опцию l (маленькая L): $ grep -rnwl DEADBEEF Поиск в определенном каталоге и его подкаталогах. Следующий пример начнет поиск слова USB в файлах каталога /var/log и его подкаталогах: $ grep -rnw USB /var/log Поиск только в определенных файлах. С помощью опции --include="фильтр" можно ограничить поиск только определенными файлами. Например, вот так можно искать строку "sprintf" только в заголовочных файлах: $ grep --include="*.h" -rnw sprintf А как искать слова со спецсимволами? Предположим, нужно найти вхождение последовательности символов -lmpsse, для этого нужно применить двойные кавычки, и для символа '-' применить экранирование. Иначе символ дефиса будет принят как часть регулярного выражения. $ grep -rnw "\-lmpsse" [Совместное использование find и grep] Например, следующая команда выводит список скриптов, в содержимом которых содержится слово test (поиск стартует рекурсивно с корневого каталога): # find / -name "*.sh" | grep test % ps -ax | grep inetd # pkg_info | grep -i mc-4.6.0_13 temp=`eval ifconfig $outside | grep -E -o --max-count=1 --regexp=$regex` Здесь в переменную $temp записывается результат фильтрации вывода ifconfig. Опция -E включает использование регулярных выражений в шаблоне (grep -E синоним egrep), -o включает вывод не всей строки, а только то, что совпало с шаблоном, --regexp задает шаблон - регулярное выражение. Следующая строка ищет все строки, в которых встречается слово cdp (locate cdp), но не встречается слово cdplay (grep -v cdplay): # locate cdp | grep -v cdplay | more Идея простая - grep ищет слова 25%, 50%, 75% и 100%, и выдает 52 строки перед совпадением: # more pinglog.txt | grep -f ping_patterns.txt -B 52 > pinglog_filtered.txt Теперь комментарии. Входной файл, как вы уже догадались pinglog.txt, выводит на вход grep команда more. Опция -f указывает grep брать паттерны для совпадения из файла ping_patterns.txt. Содержимое ping_patterns.txt (не забываем в конце этого файла указать возврат каретки): 25% Далее опция -B указывает включить в вывод grep еще 52 строки ПЕРЕД местом, где обнаружено совпадение с паттерном. Таким образом, в файл pinglog_filtered.txt попадет только то, что нам нужно. tail -f /var/www/httpd-logs/mydomain.ru.access.log | grep -o http://.*.html | uniq Результат: http://microsin.net/adminstuff/hardware/s-pen-galaxy-note-inside.html http://microsin.net/adminstuff/others/russia-post-sending.html http://microsin.net/programming/AVR/avr077-opto-isolated-emulation-for-the-debugwire.html http://microsin.net/adminstuff/windows/ux32vd-install-windows7-on-integrated-ssd.html http://microsin.net/adminstuff/hardware/relay-and-transistor-as-electronic-switches.html http://microsin.net/adminstuff/hardware/relay-and-transistor-as-electronic-switches.html http://microsin.net/adminstuff/others/altium-designer-howto.html http://microsin.net/programming/PC/c-sharp-faq.html http://microsin.net/programming/AVR/atmega-ct1-pulse-counting.html http://microsin.net/adminstuff/windows/move-windows-xp-to-new-hardware.html http://microsin.net/programming/PC/dll-building-and-using.html http://microsin.net/adminstuff/cisco/qos-setup-example.html В этом примере опция -o для grep указывает выводить только части совпадения с шаблоном "http://.*.html", а команда uniq оставляет только уникальные (не повторяющиеся друг за другом) строки. Вместо того, чтобы показать результат фильтрации, grep выдает: $ tail -f ~/logfile.txt | grep ADC
W (6813) ADC SINGLE: 4.28V
W (6813) ADC SINGLE: 4.27V
W (6813) ADC SINGLE: 4.23V
Двоичный файл (стандартный ввод) совпадает
Проблема связана с тем, что на вход grep могли попасть символы с многобайтной кодировкой (например ESC-коды или UTF8). Для решения проблемы необходимо в командную строку grep добавить опцию -a: $ tail -f ~/logfile.txt | grep -a ADC
Опция -a (и её синоним --text) указывает обрабатывать двоичный входной файл так же, как это был бы текстовый файл. Указание опции -a также эквивалентно указанию --binary-files=text в командной строке. Это можно сделать с помощью опции --exclude-dir=имя_каталога. Пример, который ищет точное вхождение строки CMAKE_CXX_COMPILER_VERSION в файлах каталога ../.., исключая при этом папку ./build: $ grep --exclude-dir=build -rnw CMAKE_CXX_COMPILER_VERSION ../..
Это можно сделать с помощью опции --exclude=какие_файлы_искать_не_надо. Пример, который ищет точное вхождение строки riscv64-unknown-elf в файлах каталога ../.., исключая при этом все файлы, оканчивающиеся на .a и .map: $ grep --exclude="*.map" --exclude="*.a" -rnw "riscv64-unknown-elf" ../..
[Ссылки] 1. Мой переход с Windows на Ubuntu. |