UGREP и все о нем

Удивительная поисковая программа на все случаи жизни. Детальный разбор

Примеры использования поисковых запросов POSIX

Установка UGREP

pkg install ugrep

Файл конфигурации .ugrep хранится в корне домашнего каталога

ug –save-config OPTIONS

сохранит новые настройки

Я уже в восторге от UGREP

Примеры

ПримерОписание
ug -Qзапускает интерактивный режим поиска
ug -%% -jwQрекурсивный Google поиск по словам с интерактивностью
ug PATTERNискать во всех файлах по паттерну рекурсивно
ug PATTERN FILEискать в конкретном файле
ug PATTERN DIRискать в конкретной директории
ug -3 PATTERN DIRискать рекурсивно до 3-го уровня вложенности
ug -3 -g"foo*.txt" PATTERN DIRискать только в именах файлов foo*.txt нужный паттерн в директории DIR не глубже 3-го уровня
ug -z PATTERNискать в архивах
ug -z -tc,cpp -Z PATTERNискать в архивах коды С и С++ с неточным совпадением -Z паттерна
ug -z -l "" package.zipпокажет все файлы в архиве
ug -z -W –pager "" mailattachment.zipпросмотреть 16-ричный дамп в архиве
ug –save-config –ignore-files –ignore-binary –decompressсохранит файл конфигурации игнорируя bin и .git файлы и смотреть в архивах
ug –help regexпокажет help команды

Опции UG со списком файлов

ОпцияОписание
-lсписок файлов, удовлетворяющих паттрену
-l -m5,список файлов, где есть не меньше 5 совпадений
-l –max-files=3только первые 3 файла с совпадениями
-Lвсе файлы не совпавшие с паттерном
-cпосчитать сколько совпадений в файле
-cvпосчитать сколько несовпадений в файле
-cuпосчитать совпадения
-cm1,посчитать совпадения, но не показывать с 0

Опции UG для отображения результата

ОпцияОписание
-Hвыводить имя файла
-nвыводить номер строки
-kвыводить номер колонки
-bвыводить номер байта с начала файла
-uразделяет групповые запросы и выводит результат раздельно
-C3мощно! выводит 3 строки до совпадения (-B3) и 3 строки после (-A3)
-yвыводит весь файл и подсвечивает найденные строки
-oвыводит только найденные фразы
-o -C20выведет 40 строк вокруг каждого найденного значения
–width=40выведет результат шириной 40 знаков

Опции управления паттерном

ОпцияОписание
-Fискать как fgrep
-Gискать как grep
-Pискать как perl
-Zискать как fuzzy (приблизительно)
-Uискать не как Unicode
-Yискать как grep
-iискать регистронечувствительно
-jискать умно регистронезависимо
-wискать целиком слова, а не части слов
-xискать целыми строками
-vинверсия паттерна
-e PATTERNможно складывать выражения поиска
-N PATTERN-e “[0-9]+” -N “0+” ищет ненулевые числа
-f FILEчитает из файла паттерн
-f cpp/namesнаверно очень нужная вещь, для тех кто пишет на С

Googling files

непереводимая вещь, но смысл типа ищем как гуглинг

ОпцияОписание
-% “foo bar”чтобы в одной строке было оба паттерна
-%% “foo bar”чтобы в одном файле было оба паттерна
-% “foo -bar”чтобы в одной строке был 1-й, но не было второго
-%% “foo -bar”чтобы в одном файле был 1-й, но не было второго
-% “foo bar|baz”чтобы в одной строке был или 1-й или 2-й
-% “foo -(bar|baz)”чтобы в строке был 1-й, но не было ни второго и не третьего
-% “foo AND NOT (bar OR baz)”аналогично выше
-% “foo -bar -baz”чтобы в строке был 1-й и не было 2-го и 3-го вместе
-% ‘foo “-bar baz”’чтобы был первый без второго но с третьим
-F -% “foo bar?”с фиксацией поиска

Приблизительный поиск

ОпцияОписание
-Zискать приблизительно, допускается один символ не совпадающий в шаблоне (вообще три темы в таком поиске: - недостающий символ; - лишний символ; - замененный символ)
-Z2все тоже самое, что выше но теперь с двумя символами
-Z+2этот поиск конкретно указывает, что только могут быть лишние 2 символа
-Z-2этот поиск конкретно указывает, что только могут быть недостающие 2 символа
-Z~2этот поиск конкретно указывает, что только могут быть 2 символа замененные
-Z+-2этот поиск конкретно указывает, что только могут быть лишние и недостающие 2 символа
-Z+-~2это аналог -Z2
-c -Zпосчитаем сколько было таких неудачных совпадений
-c -Zbest2посчитаем только с лучшими вариантами, плохие отбросит
-c -Zbest2 –sort=bestпосчитает все, но выведет в отсортированном виде по степени ухудшения

Ищем в архивах

Это уже для меня конкретное откровение! Чтобы grep еще и в архивах искал

ОпцияОписание
-zищет в zip/7z/tar/pax/cpio архивах, и в сжатых файлах tarballs и gz/Z/bz/bz2/lzma/xz/lz4/zstd/brotli
-z –zmax=2ищет также, как и выше, но не больше 2-го уровня вложенности архивов в архивы
-z -I –zmax=2как и выше, но не ищет в двоичных файлах
-z -tc,cppищет в архивах и файлы типа С и С++ (ключ t указывает тип файла)
-z -g".txt,.md"работает как find и ищет в именах файлов и директорий в архивах
-z -g"^bak/"ищет в архивах, исключая bak директории

Двоичные файлы и устройства

ОпцияОписание
-Iигнорировать двоичные файлы
-Whexdump — 16-ричный двоичный код искать, а текст, как обычный текст
-Xищет двоичный код в hexdump
-U –hexdumphexdump 8-битный двоичный шаблон регулярных выражений, соответствующий шаблону на основе символов Unicode (опция -U)
–hexdump=4aвыводит четырехколоночный дамп со всеми символами
–hexdump=4chэто тоже в 4 колонки, но без символов и пробелов
–hexdump=4C3выводит дамп 3 строки перед и 3 строки после найденного паттерна
–hexdump=4C3 -u -bпохожа, как выше, но разгруппирует запрос и укажет байт адрес в файле
-Dreadищет на специальном устройстве

опции для –hexdump

получает аргументы

  • [1-8] — количество колонок дампа
  • [a] — все выводить
  • [bch] — не выводить символы, пробелы и байт коды
  • [A[NUM]][B[NUM]][C[NUM]] — строки перед и после

Ищет по двоичному коду:

 ug -X 'ffffff'

000a9660  41 41 67 42 2c 43 41 43  70 42 2c 51 41 41 51 2c  |AAgB,CACpB,QAAQ,|
000a9880  41 55 2c 43 41 41 43 2c  43 41 41 43 3b 4d 41 43  |AU,CAAC,CAAC;MAC|
000a9890  35 42 2c 49 41 41 49 2c  43 41 41 43 2c 43 41 41  |5B,IAAI,CAAC,CAA|
000a98a0  43 6a 42 2c 51 41 41 51  2c 47 41 41 47 2c 49 41  |CjB,QAAQ,GAAG,IA|
000a98b0  41 49 3b 4d 41 43 72 42  2c 49 41 41 49 2c 49 41  |AI;MACrB,IAAI,IA|
000a98c0  41 49 2c 43 41 41 43 2c  43 41 41 43 73 47 2c 65  |AI,CAAC,CAACsG,e|
000a98d0  41 41 65 2c 45 41 41 45  3b 51 41 43 7a 42 78 67  |AAe,EAAE;QACzBxg|
000a98e0  46 2c 59 41 41 59 2c 43  41 41 43 2c 49 41 41 49  |F,YAAY,CAAC,IAAI|
000a98f0  2c 43 41 41 43 2c 43 41  41 43 77 67 46 2c 65 41  |,CAAC,CAACwgF,eA|
000a9900  41 65 2c 43 41 41 43 3b  51 41 43 6e 43 2c 49 41  |Ae,CAAC;QACnC,IA|
000a9910  41 49 2c 43 41 41 43 2c  43 41 41 43 41 2c 65 41  |AI,CAAC,CAACA,eA|
000a9920  41 65 2c 47 41 41 47 2c  49 41 41 49 3b 4d 41 43  |Ae,GAAG,IAAI;MAC|
000a9930  39 42 3b 49 41 43 46 3b  49 41 43 41 2c 4b 41 41  |9B;IACF;IACA,KAA|
000a9940  4b 2c 43 41 41 43 6c 37  46 2c 4d 41 41 4d 2c 43  |K,CAACl7F,MAAM,C|
000a9950  41 41 43 2c 43 41 41 43  3b 45 41 43 68 42 3b 45  |AAC,CAAC;EAChB;E|
000a9960  41 47 41 36 6e 42 2c 4f  41 41 4f 41 2c 43 41 41  |AGA6nB,OAAOA,CAA|
000a9970  41 2c 45 41 41 47 3b 49  41 43 52 2c 49 41 41 49  |A,EAAG;IACR,IAAI|
000a9980  2c 43 41 41 43 2c 49 41  41 49 2c 43 41 41 43 35  |,CAAC,IAAI,CAAC5|
000a9990  59 2c 4d 41 41 4d 2c 45  41 41 45 3b 4d 41 47 68  |Y,MAAM,EAAE;MAGh|
000a99a0  42 2c 49 41 41 49 2c 49  41 41 49 2c 43 41 41 43  |B,IAAI,IAAI,CAAC|
000a99b0  2c 43 41 41 43 34 72 46  2c 51 41 41 51 2c 45 41  |,CAAC4rF,QAAQ,EA|

Ищет по Unicode:

ug -U --hexdump 'ffffff'

zotero-pdf-translate/node_modules/yauzl/index.js
   140:   
00001910  79 4f 66 66 73 65 74 20  3d 3d 3d 20 30 78 66 66  |yOffset === 0xff|
00001920  66 66 66 66 66 66 29 29  20 7b 0a -- -- -- -- --  |ffffff)) {J-----|
   333:   
00003b60  3d 3d 20 30 78 66 66 66  66 66 66 66 66 20 7c 7c  |== 0xffffffff |||
   334:   
00003ba0  20 30 78 66 66 66 66 66  66 66 66 20 7c 7c 0a --  | 0xffffffff ||J-|
   335:   
00003be0  78 66 66 66 66 66 66 66  66 29 20 7b 0a -- -- --  |xffffffff) {J---|

выводит в красивом виде 16-ричного дампа в 4 колонки

ug --hexdump=4a 'ffffff'

zotero-pdf-translate/node_modules/yauzl/index.js
   140:   
00001900  20 63 65 6e 74 72 61 6c  44 69 72 65 63 74 6f 72  79 4f 66 66 73 65 74 20  3d 3d 3d 20 30 78 66 66  | centralDirectoryOffset === 0xff|
00001920  66 66 66 66 66 66 29 29  20 7b 0a -- -- -- -- --  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --  |ffffff)) {J---------------------|
   333:   
00003b60  3d 3d 20 30 78 66 66 66  66 66 66 66 66 20 7c 7c  0a -- -- -- -- -- -- --  -- -- -- -- -- -- -- --  |== 0xffffffff ||J---------------|
   334:   
00003ba0  20 30 78 66 66 66 66 66  66 66 66 20 7c 7c 0a --  -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- --  | 0xffffffff ||J-----------------|

выводит в 4 колонки но без пробелов и символов

ug --hexdump=4ch 'ffffff'

zotero-pdf-preview/node_modules/pdfjs-dist/legacy/build/pdf.mjs.map
     1:   
000eb440  305c222026262062 67436f6c6f72203d 3d3d205c22236666 666666665c222920 
     1|   
00112f20  7365656420262030 7866666666666666 66203a2053454544 3b5c6e2020202074 
00112f40  6869732e6832203d 2073656564203f20 7365656420262030 7866666666666666 
     1|   
00120c20  6865696768742c5c 6e20206e6f6e426c 61636b436f6c6f72 203d203078666666 
00120c40  66666666662c5c6e 2020696e76657273 654465636f646520 3d2066616c73652c 
     1|   

выводит 4 колонки и по 3 строки перед и после:

ug --hexdump=4C3 'afaf'

zotero-pdf-translate/node_modules/minimist/CHANGELOG.md
    51:   
00001200  -- -- -- 2d 20 5b 44 65  76 20 44 65 70 73 5d 20  61 64 64 20 6d 69 73 73  69 6e 67 20 60 6e 70 6d  |---- [Dev Deps] add missing `npm|
00001220  69 67 6e 6f 72 65 60 20  64 65 76 20 64 65 70 20  5b 60 33 32 32 36 61 66  61 60 5d 28 68 74 74 70  |ignore` dev dep [`3226afa`](http|
00001240  73 3a 2f 2f 67 69 74 68  75 62 2e 63 6f 6d 2f 6d  69 6e 69 6d 69 73 74 6a  73 2f 6d 69 6e 69 6d 69  |s://github.com/minimistjs/minimi|
00001260  73 74 2f 63 6f 6d 6d 69  74 2f 33 32 32 36 61 66  61 66 30 39 65 39 64 31  32 37 63 61 33 36 39 37  |st/commit/3226afaf09e9d127ca3697|
00001280  34 32 34 33 37 66 65 36  65 38 38 66 37 35 32 64  36 62 29 0a -- -- -- --  -- -- -- -- -- -- -- --  |42437fe6e88f752d6b)J------------|
   186:   
000036c0  -- -- -- -- -- 2d 20 5b  44 65 76 20 44 65 70 73  5d 20 61 64 64 20 6d 69  73 73 69 6e 67 20 60 6e  |------ [Dev Deps] add missing `n|
000036e0  70 6d 69 67 6e 6f 72 65  60 20 64 65 76 20 64 65  70 20 5b 60 33 32 32 36  61 66 61 60 5d 28 68 74  |pmignore` dev dep [`3226afa`](ht|
00003700  74 70 73 3a 2f 2f 67 69  74 68 75 62 2e 63 6f 6d  2f 6d 69 6e 69 6d 69 73  74 6a 73 2f 6d 69 6e 69  |tps://github.com/minimistjs/mini|
00003720  6d 69 73 74 2f 63 6f 6d  6d 69 74 2f 33 32 32 36  61 66 61 66 30 39 65 39  64 31 32 37 63 61 33 36  |mist/commit/3226afaf09e9d127ca36|
00003740  39 37 34 32 34 33 37 66  65 36 65 38 38 66 37 35  32 64 36 62 29 0a -- --  -- -- -- -- -- -- -- --  |9742437fe6e88f752d6b)J----------|

Исключения и включения

ОпцияОписание
-@(–all) ищет во всех нескрытых файлах и отменяет все ограничения до него
-.(–hidden) включая скрытые файлы
-Iигнорировать двоичные файлы
-pне переходить по символическим ссылкам
-rискать рекурсивно без символических ссылок
-rSискать рекурсивно по символическим ссылкам на файлы, но без директорий
-Rискать рекурсивно по символическим ссылкам с директориями
-tc,cppискат только файлы типом С и С++
-Ohpp,cppсокращенная запись -g".hpp,.cpp" ищет по расширениям файлов
-g".hpp,.cpp"ищет по имена файлов
-g"src/"ищет все src/ директории рекрсивно
-g"^*.txt,^bak/"ищет файлы и директории исключая файлы *.txt и директории bak/
–iglob="^*.txt,^bak/"тоже, что выше, но регистронезависимый поиск
-K10,99искать в файлах с 10-й по 99-ю строку
-m1выводить только первую найденную строку
-m2,9выводить только со 2-й по 9-ю строку поиска
-m2,9 -uкак выше, только разруппировать результат
-3рекурсия на 3 уроня вглубь
-2-3рекурсия со 2-го по 3-й уровень
–max-files=3возвращать результат для первых трех файлов
–ignore-filesсоблюдать правила .gitignore при рекурсивном поиске
–exclude-fs=PATHисключить поиск системных файлов по пути PATH
–exclude-fsспускаться только в файловые системы с указанными целями
–include-fs=.игнорирует поиск на смонтированных дисках
–exclude-from=FILEигнорирует все файлы помеченные в переменной FILE
–include-from=FILEобратное выше, включает все файлы определенные в FILE
–filter=“COMMANDS”перед поиском, предварительно фильтрует файлы с помощью специальных комманд

Форматированый вывод результата

ОпцияОписание
--csvв CSV
--jsonв JSON
--xmlв XML
--format=“FORMAT”выводит в некоем условном формате
╭─edge@bsd in ~ 
╰$ ug -% "sed 3d" ./sed --json
[
  {
    "file": "./sed/example.md",
    "matches": [
      { "line": 6, "match": "╰$ seq 10 | sed -E  '1,3d;5d'" }
    ]
  },
  {
    "file": "./sed/example.md~",
    "matches": [
      { "line": 6, "match": "╰$ seq 10 | sed -E  '1,3d;5d'" }
    ]
  }
]

получилось очень мило

У grep бывает все красиво

ОпцияОписание
--pretty— выводит все красочно и красиво и включает -n, -T, --color, --tree, --heading, --break и --sort
--tree— добавляет деревянной красоты к ключам -l и -c когда выводим списо файлов
--heading— выводит имя файла как заголовок в поиске
--break— выведет пустую линию между результатами поиска
-T— добавит \tab в строке и колонке с номером
--color— выводит в цвете
--colors=COLORS— задать цвет вывода
--hyperlink=+— включает гиперссылки в вывод на терминал
--pager— мне это очень напомнило редактор vi в режиме просмотра. Т.е. смотрим на вывод постранично
--tagoutput matches as match instead of colorizing them, where --tag=TAG,TAG outputs TAGmatchTAG
--replace=“FORMAT”replace matches in the output by FORMAT, see also ug --help format
--separator=SEPspecify SEP to separate line and column numbers from the match
--group-separator=SEPspecify SEP to separate context for options -ABC
--widthtruncate lines to the terminal window width; --width=40 truncates to 40 characters

Так будет выглядеть вывод в дереве

╭─edge@bsd in ~ 
╰$ ug -l ".*\.man"         
.zsh_history
emacs-29.4.core

.cache/
╰╴chromium/
│ ╰╴Default/
│ │ ╰╴Cache/
│ │ │ ╰╴Cache_Data/
│ │ │ │ ╰╴02c12a7839f51358_0
│ │ │ │ ╰╴3c7eb053e143ec36_0
│ │ │ │ ╰╴40051ca56893c175_0
│ │ │ │ ╰╴6fa460d8b7921dfc_0
│ │ │ │ ╰╴87d71ae3063c69c0_0
│ │ │ │ ╰╴90a53aad17d58184_0
│ │ │ │ ╰╴9da1f7ca347c666b_0
│ │ │ │ ╰╴a96d92547e75daa0_0
│ │ │ │ ╰╴c1df79e2d6a936bc_0
│ │ │ │ ╰╴c4bbc1e0b652d750_0
│ │ │ │ ╰╴c7b98cb5b80c61a8_0
│ │ │ │ ╰╴d446ead8e6fafe30_0
│ │ │ │ ╰╴f48eb8aee3d80bd8_0
│ │ │ ▔ 
│ │ ╰╴Code Cache/
│ │ │ ╰╴js/
│ │ │ │ ╰╴00d8a21e14d11b61_0

Globs

эти шарики делают поиск по файлам и директориям

КомандаОписание
-gстандартны режим “паттерн”
--iglob=поиск регистро нечувствительное имя файла или директории
--exclude=исключить из поиска файлы
--include=включить в поиск файлы
--include-dir=включая директории
--exclude-dir=исключая директории
--include-from=fileфайл с именами включаемыми в поиск
--exclude-from=fileфайл с имена не включаемыми в поиск
--ignore-files=fileфайл с именами игнорируемые в поиске

Паттерны glob

КомандаОписание
*ищет все
?ищет любой один символ
[abc-e]ищет в этой позиции символы abcde
[^abc-e]ищет символы в этой позиции кроме a,b,c,d,e,/
[!abc-e]тоже, что выше
/ищет только в текущей директории
**/ищет в предыдущих дирикториях
/**ищет в последующих директориях
\?ищет любой спец.символ

Продолжение следует…