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




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


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 и pgrep, то результат будет пожалуй удобнее, чем 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.
<http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/12292/focus=12318>.
see <http://thread.gmane.org/gmane.comp.lib.gnulib.bugs/12015/>.
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, только вместо файла указывается название пакета.





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 <inomics-alert@inomics.com>
Reply-To: Inomics <inomics-alert@inomics.com>
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 форматы.

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


Поделиться с друзьями
-->

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


  1. datacompboy
    30.11.2016 22:24
    +12

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


    1. datacompboy
      30.11.2016 22:34
      +4

      а еще удивлён, что ngrep помер… я им всего-то года два назад активно пользовался


    1. temujin
      30.11.2016 22:48

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


      1. datacompboy
        30.11.2016 22:51
        +12

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

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


    1. ValdikSS
      01.12.2016 02:45
      +3

      psgrep() { ps up $(pgrep -f $@) 2>&-; }
      
      $ psgrep firefox
      USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
      valdikss 29815  0.0  0.0 118988  2756 ?        S    Nov30   0:00 /bin/sh /usr/local/bin/firefox
      valdikss 29817  0.0  0.0   9884  2116 ?        S    Nov30   0:00 firejail firefox
      valdikss 29818  0.0  0.0   9884  1968 ?        S    Nov30   0:00 firejail firefox
      valdikss 29821 19.5 11.0 11270608 887336 ?     Sl   Nov30 182:04 /usr/lib64/firefox/firefox


    1. Krepver
      01.12.2016 07:17
      +3

      Спасибо! А то я всегда делал
      ps | grep asterisk | grep -v grep


      1. user_id
        01.12.2016 10:26
        +3

        А я и дальше так буду делать, потому как предназначение квадратных скобок не очевидно настолько, насколько может быть не очевидно. Явно лучше чем неявно, не считая того, после вставки текста для grep мне нужно перемещаться куда-то и его редактировать. Но теперь у меня есть pgrep и я этому счастлив


        1. datacompboy
          01.12.2016 12:27

          не забываем, что grep ищет еще и по аргументам, а pgrep (по умолчанию) только по имени процесса.

          ну и еще один простой способ — добавить \\ перед любой буквой.

          например
          `ps | grep asteris\\k`


          1. JIghtuse
            01.12.2016 15:33

            А почему именно ps+grep? Мне кажется, добавить один флаг pgrep проще, чем писать конвейер. Да и есть этот pgrep даже в busybox (разве что, флаг -a там отстутствует, иногда не хватает).


            1. datacompboy
              01.12.2016 15:48
              +2

              потому, что pgrep это еще одна сущность, чтоб держать в голове.
              опять же, ps+grep ищет еще по пидам (да, это удобно иногда).

              опять же, вывод разный:

              ~$ ps -aux | grep nt\\p
              ntp 4249 0.0 0.0 22960 1920? Ss нояб.29 0:12 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 117:125

              ~$ ps -aux | pgrep ntp
              4249

              ~$ ps -aux | pgrep -a ntp
              4249 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 117:125

              как у pgrep искать по тредам? и еще миллион вариантов


    1. simpleadmin
      01.12.2016 13:05
      +1

      то есть не `ps | grep asterisk` а `ps | grep [a]sterisk`

      Добавлю ещё, что Николай ZyXI убедил меня (по крайней мере для Bash) брать часть содержащую раскрывающуюся символьный класс в кавычки. Аргументы:
      Трюк пропадёт в никуда, если в каталоге есть файл XXXX

      [alex@d /usr/home/Alex]$ ps afx | grep ntpd
      656 - Ss 0:57.56 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
      38412 0 S+ 0:00.00 grep ntpd
      [alex@d /usr/home/Alex]$ ps afx | grep [n]tpd
      656 - Ss 0:57.56 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
      [alex@d /usr/home/Alex]$ touch ./ntpd
      [alex@d /usr/home/Alex]$ ps afx | grep [n]tpd
      656 - Ss 0:57.56 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
      38435 0 S+ 0:00.00 grep ntpd
      [alex@d /usr/home/Alex]$ ps afx | grep "[n]tpd"
      656 - Ss 0:57.56 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
      [alex@d /usr/home/Alex]$ rm ./ntpd
      [alex@d /usr/home/Alex]$ ps afx | grep [n]tpd
      656 - Ss 0:57.57 /usr/sbin/ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift
      [alex@d /usr/home/Alex]$


      1. datacompboy
        01.12.2016 13:26

        ну так это просто трюк для «здесь и сейчас», не для скриптинга. для скриптинга следует использовать pidof / pgrep / etc.

        вариант с двумя слешами иммунен к файлу


        1. simpleadmin
          01.12.2016 16:08
          +3

          вариант с двумя слешами иммунен к файлу

          Ни в коем разе не придираюсь, но таки и этот вариант не безгрешен, например:
          [alex@d /usr/home/Alex]$ touch ttyv1
          [alex@d /usr/home/Alex]$ ps afx | grep ttyv1
          3805 v1 Is+ 0:00.00 /usr/libexec/getty Pc ttyv1
          43929 0 S+ 0:00.00 grep ttyv1
          [alex@d /usr/home/Alex]$ ps afx | grep ttyv\\1
          grep: Invalid back reference
          [alex@d /usr/home/Alex]$ ps afx | grep "ttyv[1]"
          3805 v1 Is+ 0:00.00 /usr/libexec/getty Pc ttyv1
          [alex@d /usr/home/Alex]$

          То есть луше всё-таки закавычивать.


          1. datacompboy
            01.12.2016 16:17

            «перед любой буквой», это да, важно.

            во всяком случае, еще не напарвался над тем, чтоб не работало :)
            (еще раз, на всякий случай, disclaimer: это НЕ для скриптинга, это для ad-hoc разбирательств)


    1. Hissing_Bridge
      01.12.2016 16:32

      Лично я сделал мини-функцию:

      function nogrep {
        command grep --color=always $@ | command grep -v "grep"
      }
      export -f nogrep
      

      Если использовать фильтрацию руками, можно использовать маску
      grep som\\e
      grep [^]]some
      


      1. datacompboy
        01.12.2016 19:10

        «grep -v grep» тоже не панацея, так как ломает, например, любые процессы которые работают с файлом с именем tobegrepped, например :)


        1. Hissing_Bridge
          01.12.2016 20:19

          если такой уж частный случай рассматривать, то можно egrep -v "\sgrep\b"


          1. ZyXI
            01.12.2016 20:25
            +1

            А теперь вы хотите найти strace, в котором запущен какой?то другой grep


            1. simpleadmin
              01.12.2016 21:35
              +2

              Ну если уж принципиально не использовать квадратные скобки исключаем тривиальный вариант:
              $ ps afx | grep -w "[g]rep" | grep -vF "[g]rep"
              30596 pts/13 S+ 0:00 | \_ strace grep . /dev/random
              30599 pts/13 S+ 0:00 | \_ grep . /dev/random

              и делаем с круглыми:
              $ ps afx | grep -w "grep" | grep -vE "(grep).*\1"
              30596 pts/13 S+ 0:00 | \_ strace grep . /dev/random
              30599 pts/13 S+ 0:00 | \_ grep . /dev/random

              :)


              1. bel-bes
                02.12.2016 10:48

                А можно разжевать подробнее как это работает. Оба варианта.
                Понял что оба работают, но не понял почему.


                1. simpleadmin
                  02.12.2016 12:23

                  $ ps afx | grep -w "[g]rep" | grep -vF "[g]rep"
                  в 1-м grep символьный класс [g] раскрывается в g, то есть поиск происходит по слову grep, а в список процессов попадает [g]rep. Вторым грепом мы его исключаем из списка, так как благодаря -F [g] не раскрывается.

                  $ ps afx | grep -w «grep» | grep -vE "(grep).*\1"
                  Здесь используется специальная конструкция \1 которая позволяет обратиться к уже найденной с помощью символов группировки подстроке, и данная строка использованием -v исключается из списка.

                  Всё это, конечно лучше делать с помощью pgrep и т.п. Вероятность накосячить в скриптах в таких конструкциях близка к 100%


            1. Hissing_Bridge
              02.12.2016 03:33

              Разумеется, это лишь примеры, ты сам должен понимать конкретный случай, задачу и реализацию.


              1. ZyXI
                02.12.2016 08:52

                Если я хочу получить номер процесса в каком?то скрипте, то ps afx | grep я вряд ли буду когда?либо использовать: есть ps -C, killall (нет, pgrep я обычно не использую). Если мне нужен номер процесса или что?то ещё посмотреть самому (даже и с целью передать потом «нужные» номера kill, скорее всего, просто переписав), то заморачиваться с исключением grepа мне не нужно вообще.


                Здесь я просто показываю, что ps afx | grep — не лучший выбор, если нужна точность. Тот же strace с grepом проще искать через ps -C strace -o pid=,cmd= | grep -w grep (да, ps | grep, но второй grep тут в списке не покажется никогда, как и собственно процесс, запущенный под strace). Единственное но: -C не работает в cygwin и в BSD системах.


                1. datacompboy
                  02.12.2016 18:05

                  вообще, чтоб пид получить лучше всего pidof имхо. еще и читабебельнее


                  1. ZyXI
                    02.12.2016 19:19
                    +1

                    Для «ручного» поиска ps лучше: поискали, не нашли, исправили что?то, нашли, убрали ненужные столбцы из -o, дописали pipe (или, как я чаще делаю, просто переписали PID). С pidof будет много возни, когда вы захотите проверить результаты поиска, или если внезапно обнаружите, что вам, на самом деле, нужно ещё уточнить, с какими аргументами программа запущена. Проще выучить один ps и всегда использовать его, чем переколбашивать командную строку для использования pidof, а в скриптах я предпочитаю использовать знакомые инструменты.


  1. farcaller
    01.12.2016 00:23

    Pdfgrep не поддерживает расширенные регулярные выражения

    Но поддерживает POSIX и PCRE?..


  1. CaptainFlint
    01.12.2016 00:30
    +2

    Что странно, системные вызовы read все время одни и те же, вне зависимости от поиска.
    А с чего бы им отличаться? Как читал файл, так и читает, просто потом сравнивает содержимое буфера с разными строками.


  1. chabapok
    01.12.2016 01:12
    +3

    Гораздо интересней не чтобы слово grep было в названии исполняемого файла, а схожесть функционалу.
    тот же zgrep не умеет работать с ключом -R, чтобы искать по всем файлам в каталоге.
    А вот есть пакет silversearcher-ag и в нем есть утилита ag. Она это умеет.


  1. leggiermente
    01.12.2016 01:22

    Помню, как при помощи pdfgrep анализировал проприетарную программу, которая наиболее полный output делала только в pdf.


  1. ZyXI
    01.12.2016 02:28

    Вместо ps | grep или pgrep почти всегда использую ps -C, иногда с дополнительным grep: результаты, как правило, содержат меньше мусора. Остальными grepами не пользуюсь; pdfgrep показался полезным, но я о нём просто не слышал.


    Также вместо grep -r обычно использую ag, он справляется лучше.


  1. DeLuxis
    01.12.2016 06:29

    Подскажите пожалуйста, как решить такую проблему: нужно найти файлы содержащие вхождений по регулярке, вхождений может быть несколько, а потом сохранить все вхождения (группировка в регулярном выражении) в файл в виде списка?


    1. Angel2S2
      01.12.2016 10:58
      +1

      grep -REho 'regexpr' ./* > fileout


      1. Angel2S2
        01.12.2016 11:02
        +1

        или

        grep -REho 'regexpr1|regexpr2|...' ./* > fileout
        


        1. DeLuxis
          01.12.2016 11:47
          -1

          Спасибо!


  1. Deosis
    01.12.2016 06:56
    +1

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

    Сразу возникла мысль: как deepgrep обработает рекурсивный архив?
    А есть утилита anygrep. которая распознает тип переданного файла/каталога/пакета/etc. и перенаправит запрос одной из утилит, описанных в статье?


  1. Qwiz
    01.12.2016 07:17
    +4

    ngrep медленно, но все же развивается. Уже на гитхабе.
    https://github.com/jpr5/ngrep


    1. temujin
      01.12.2016 10:29

      Автор вроде тот же — Jordan Ritter. Будем следить.


  1. AlexMal
    01.12.2016 07:17

    На днях стояла задача: Вычислить PID определенного процесса. Эксперименты сошлись к двум вызовам:

    > pgrep -f process_name
    > ps -afx | grep "process_name" | grep -v grep | awk '{print $1}'
    


    1. Stanislavvv
      01.12.2016 10:26
      +1

      Есть утилита pidof
      В дебиане входит в пакет sysvinit-utils


  1. Igelko
    01.12.2016 08:03
    +3

    для грепа исходников есть няшные ack (пакет ack-grep в дебиане) и ag. Они не лазят во всякие .git, .svn, бинарники и хорошо настроены по дефолту для подсветки итд.


  1. ozkriff
    01.12.2016 10:34
    +4

    Я добавлю еще ripgrep:


    ripgrep combines the usability of The Silver Searcher with the raw speed of grep.

    http://blog.burntsushi.net/ripgrep


    https://github.com/BurntSushi/ripgrep


    Хотя меня, конечно, как растофанатика в первую очередь интересует просто то что он написан на Rust)


  1. Angel2S2
    01.12.2016 11:23
    +1

    grepmail — аналог mboxgrep


  1. am-amotion-city
    01.12.2016 13:06

    *.xlsx не является проприетарным форматом. Это обычный Open XML Spreadsheet. Иными словами, это зипованный XML.


    *.xls — тот да, являлся.


  1. Acid_Jack
    01.12.2016 13:35

    exiqgrep — Search in the exim queue

    Пример удаления из очереди всех сообщений от определённого отправителя:

    exiqgrep -i -f sender@example.com | xargs exim -Mrm
    


  1. sabio
    01.12.2016 15:20

    pcre2grep — поиск с «нормальным» (PCRE) синтаксисом регулярных выражений и всякими удобными штуками, вроде вывода отдельных групп из регулярного выражения.

    Там, где grep требует экранировать скобки и другие мета-символы (?, +, |) (или не забывать указывать опцию -E), pcre2grep обрабатывает их, как того и ожидаешь в регулярных выражениях:
    grep "\(group\)\?" file.txt
    и
    pcre2grep "(group)?" file.txt

    http://www.pcre.org/current/doc/html/pcre2grep.html


    1. JIghtuse
      01.12.2016 15:37

      Можно egrep вместо grep писать, результат будет тот же. Во многих дистрибутивах просто в grep -E раскрывается, никаких зависимостей не просит.


    1. Biga
      01.12.2016 21:11

      Да чего уж там, просто используем перл: perl -ne '/(group\S*)/ && print $1,$/;'
      Можно и более сложные штуки делать, которые grep не потянет.


  1. Hissing_Bridge
    01.12.2016 16:50
    +2

    Может кому-нибудь пригодится. Использование grep like a cat, с подсветкой патерна:

    egrep --color "patern|$" file
    # For example
    egrep --color "/dev/sdb|$" /etc/fstab
    

    image

    Для тех кто немного не понял что происходит:
    egrep ищет совпадения с двумя патернами: непосредственно patern в примере и $ — конец строки, т.е. выводит все строчки в любом случае, а --color будет подсвечивать нужный нам патерн (конец строки невидимый символ, поэтому выделяется только первый патерн).

    Для удобства можно вынести в функцию:
    function gcat {
      command egrep --color "$1|$" ${@:2}
    }
    export -f gcat
    

    Первый аргумент патерн, далее остальные аргументы, в частности файл/ы