Grep все, что можно

Про grep знают если не все, то многие читатели Хабра, однако его многочисленных родственников знают немногие.


e75a77bd22b042a5a8a7abbf4eacac81.png


Давайте узнаем, как можно грепать все, что таит в себе хоть крупицу текста.


pgrep


Команда pgrep грепает список исполняемых процессов.


(5:573)$
pgrep bash
1772
11003
20678

С ключом -a, команда также выдаст всю командную строку.


(5:574)$
pgrep -af bash
1772 -bash
11003 /bin/bash
20678 /bin/bash
23567 -bash

Если правильно комбинировать ps и psgrep, то результат будет пожалуй удобнее, чем ps -ef |grep process_name, так как не содержит саму команду grep.


(5:575)$ ps wup $(pgrep bash)
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1772  0.0  0.0  21572  3020 tty1     S+   ноя19   0:00 -bash
user     11003  0.0  0.0  21384  3772 pts/3    Ss   ноя28   0:00 /bin/bash
user     20678  0.0  0.0  21396  3604 pts/1    Ss+  ноя24   0:00 /bin/bash
root     23567  0.0  0.0  21364  3016 tty2     S+   ноя21   0:00 -bash
946/7720MB      0.48 0.94 1.00 1/352 20403

zipgrep, zfgrep, bzfgrep, xzfgrep


Можно искать ключевое слово, паттерн напрямую из архива с помощью этих команд.


(5:576)$ zipgrep -i exception apptrace.zip
jboss.stderr:java.lang.NumberFormatException: For input string: "4718-4e99-bc84-828a7bf7f254"
jboss.stderr: at java.lang.NumberFormatException.(NumberFormatException.java:65)
(5:576)$
(5:576)$ bzfgrep -w bugs /usr/share/doc/coreutils-8.25/README.bz2
that distribution and found and reported bugs.
.
see .
Reporting bugs:
subtle bugs.
When reporting bugs, please include in the subject line both the package

Утилиты поддерживают расширенные регулярные выражения и имеют свой аналог egrep.


Fixed Strings Basic RegExps Extended RegExps
zfgrep zgrep zegrep
bzfgrep bzgrep bzegrep
xzfgrep xzgrep xzegrep

Каким пакетам они принадлежат?


(5:777)$ equery belongs $(which zgrep zipgrep bzgrep xzgrep)
 * Searching for /usr/bin/zgrep,/usr/bin/zipgrep,/usr/bin/bzgrep,/usr/bin/xzgrep ... 
app-arch/bzip2-1.0.6-r7 (/usr/bin/bzgrep)
app-arch/gzip-1.8 (/usr/bin/zgrep)
app-arch/unzip-6.0_p20 (/usr/bin/zipgrep)
app-arch/xz-utils-5.2.2 (/usr/bin/xzgrep)

Сравниваем с grep способность парсить расширенные регулярки и радуемся результату.


(5:578) grep -oE '\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b' /var/log/emerge.log |tail -n 3
7.2.6.8
213.180.204.183
213.180.204.183
(5:579)
(5:579) bzegrep -o '\b[0-9]{1,3}(\.[0-9]{1,3}){3}\b' /tmp/emerge.log.bz2 |tail -n3
7.2.6.8
213.180.204.183
213.180.204.183

pdfgrep


Программа идет с одноименным пакетом.


(5:580)$ eix pdfgrep
[I] app-text/pdfgrep
     Доступные версии:      1.3.2 1.4.1-r1 {+pcre test unac}
     Установленные версии:  1.4.1-r1(14:10:46 29.11.2016)(pcre -test -unac)
     Домашняя страница:     http://pdfgrep.org/
     Описание:              A tool similar to grep which searches text in PDFs

Команда парсит pdf файлы и делает все то, что положено grep.


(5:581)$ pdfgrep -i outdiscards ebook/linux_netw.pdf 
IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);

Pdfgrep не поддерживает расширенные регулярные выражения, тем не менее это очень полезная программа. Я довольно часто открываю pdf-ки и ищу в них текст, пока не вспомню в какой книге было то, что мне нужно и так теряю уйму времени. Теперь буду знать.


dgrep


Дебианщикам может быть знаком dgrep, который идет с пакетом debian goodies. Команда вызывается так же как и обычный grep, только вместо файла указывается название пакета.


e32faaa313f343e68fede17161f89577.png



Fixed Strings Basic RegExps Extended RegExps
dfgrep dgrep degrep
- dzgrep -

Верхние три ищут в текстовых файлах, а dzgrep — в архивных.


msggrep, mboxgrep


Это совсем уже узко специализированная штуковина, чтобы парсить каталоги локализации. Идет в комплекте с пакетом gettext. Программа не из разряда пользовательских, но если очень нужно, можно запустить с командной строки.


(5:752)$ msggrep -K -e help /usr/share/locale/ru/cups_ru.po

И получить такой вывод на экран
msgid ""
msgstr ""
"Project-Id-Version: CUPS 2.0\n"
"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n"
"POT-Creation-Date: 2015-07-20 14:24-0400\n"
"PO-Revision-Date: 2015-01-28 12:00-0800\n"
"Last-Translator: Aleksandr Proklov\n"
"Language-Team: PuppyRus Linux Team\n"
"Language: Russian\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"

msgid " --help Show help."
msgstr " --help Показать справку."

msgid " --help Show this help."
msgstr " --help Показать эту справку."

Следующий экспонат — парсер почтовых ящиков mboxgrep. Проект так и не взлетел, его разработка прекращена. По идее он должен был находить паттерны в письмах и обрабатывать вывод так как будто это отдельные файлы. Однако, для начала он эти паттерны должен уметь находить.


(5:753)$ grep Inomics docs/PocoMail.bak/Mail/Trash.mbx
From:     Inomics 
Reply-To: Inomics 
Subject: Inomics Alert Service
following is a list of new job openings in Inomics, the=
Inomics!
You can always unsubscribe from the Inomics Job Alert service by=
plying to this mail with the words "Inomics-Job-Unsub#1avwnr55di"=

А он не находит.


(5:754)$ mboxgrep Inomics docs/PocoMail.bak/Mail/Trash.mbx
(5:755)$

Что странно, системные вызовы read все время одни и те же, вне зависимости от поиска.


(5:779)$ strace -e trace=read -o strace_inomics mboxgrep Inomics Mail/Trash.mbx
(5:780)$ strace -e trace=read -o strace_freenet mboxgrep freenet Mail/Trash.mbx
(5:781)$ diff strace_inomics strace_freenet;md5sum strace_*
14b7de546a2a776006ad2a6440b680fd  strace_freenet
14b7de546a2a776006ad2a6440b680fd  strace_inomics

Любопытно было бы узнать, завелась ли данная программа успешно у кого-нибудь?
Ну ладно, мы увлеклись, а греп семейство еще не инвентаризировано полностью.


ssgrep


Нужно установить пакет Gnumeric. Умеет шерстить электронные таблицы, в том числе проприетарный Excel формат. Ругается на него, но делает.


(5:782)$ ssgrep Date files/*.xlsx
Неопределённый индикатор числового формата "43"
Неопределённый индикатор числового формата "41"
Неопределённый индикатор числового формата "44"
Неопределённый индикатор числового формата "42"
Unexpected element 'workbookProtection' in state: workbook
Дата рождения/Date of Birth
(5:783)$ grep Date files/*.xlsx
(5:784)$

Расширенные регулярные выражения не поддерживает. Вполне полезная штука, рекомендую.


ngrep


Еще один заброшенный проект на SourceForge. Программа представляет из-себя гибрид tcpdump и grep, причем к первому гораздо ближе, чем ко второму.


Наблюдение за сетевым трафиком по порту syslog и ключевому слову.


$ ngrep -d any 'error' port syslog

Наблюдение за сетевым трафиком по порту ftp и ключевым словам без учета регистра, сравнивать слова целиком.


$ ngrep -wi -d any 'user|pass' port 21

По-строчный вывод http трафика.


$ ngrep -W byline port 80
interface: eth0 (64.90.164.72/255.255.255.252)
filter: ip and ( port 80 )
####
T 67.169.59.38:42177 -> 64.90.164.74:80 [AP]
GET / HTTP/1.1.
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; X11; Linux i686) Opera ...
Host: www.darkridge.com.
Accept: text/html, application/xml;q=0.9, application/xhtml+xml;q=0.9 ...
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1.
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0.
Cookie: SQMSESSID=5272f9ae21c07eca4dfd75f9a3cda22e.
Cookie2: $Version=1.
Cache-Control: no-cache.
Connection: Keep-Alive, TE.
TE: deflate, gzip, chunked, identity, trailers.

А еще есть киллер-фича. Можно задать hex строку, которой ngrep сопоставляет бинарные данные пакета. Например, можно задать сигнатуру завирусованной гифки, чтобы затем настроить файрвол на раннее обнаружение.


$ ngrep -xX '0xc5d5e5f55666768696a6b6c6d6e6' port 80
interface: eth0 (64.90.164.72/255.255.255.252)
filter: ip and ( port 80 )
match: 0xc5d5e5f55666768696a6b6c6d6e6

Жаль, что разработка проекта прекращена, может в итоге получиться вполне годный самоворо-паровозо-вертолет парсер и анализатор сетевого трафика.


deepgrep


Под конец можно помянуть не-юниксвейные агрегаты поиска, такие как deepgrep от KDE strigi-utils.


Программа умеет шукать искать в файлах формата:


  • tar
  • ar / deb
  • rpm (но не cpio)
  • gzip/gz
  • bzip2/bz2
  • zip, а значит и jar/war, а также документы OpenOffice.org/LibreOffice
  • MIME сообщения (т.е. прикрепленные файлы в емайле)

Умеет искать в архивах, вложенных друг в друга.


$ deepgrep bar foo.ar
foo.ar/foo.tar/foo.tar.gz/foo.zip/foo.tar.bz2/foo.txt.gz/foo.txt:foobar
foo.ar/foo.tar/foo.tar.gz/foo.zip/foo.tar.bz2/foo.txt.gz/foo.txt:bar

Из недостатков.


  • Практически отсутствуют опции командной строки.
  • Плохо документирована.
  • Код возврата никак не связан с результатом поиска.
  • Отсутствует поддержка сжатия с использование LZMA алгоритма: lzma, xz, lzip, 7z, а также lzop, rzip, cab. cpio, xar, rar, .Z форматы.

Использованные материалы


  • grep everything
  • deppgrep: grep nested archives with one command
  • ngrep — network grep

Комментарии (4)

  • 30 ноября 2016 в 22:24

    +2

    hint: чтоб не находить сам grep в ps | grep, я оборачиваю одну букву в квадратные скобки.
    то есть не `ps | grep asterisk`, а `ps | grep [a]sterisk`
    • 30 ноября 2016 в 22:34

      +1

      , а еще удивлён, что ngrep помер… я им всего-то года два назад активно пользовался
    • 30 ноября 2016 в 22:48

      0

      Спасибо, так действительно нет рекурсии. Интересно, за счет чего выпадает ps | grep из вывода?

      • 30 ноября 2016 в 22:51

        0

        потому что у нас есть процесс с именем «grep asterisk», и он попадает под маску «asterisk».
        , а «grep [a]sterisk» НЕ попадает под маску «asterisk», из-за квадратных скобок.

        Квадратные скобки означают «набор из одного символа a».

© Habrahabr.ru