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 игнорировать двоичные файлы
-W hexdump — 16-ричный двоичный код искать, а текст, как обычный текст
-X ищет двоичный код в hexdump
-U –hexdump hexdump 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 в режиме просмотра. Т.е. смотрим на вывод постранично
--tag output 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=SEP specify SEP to separate line and column numbers from the match
--group-separator=SEP specify SEP to separate context for options -ABC
--width truncate 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] тоже, что выше
/ ищет только в текущей директории
**/ ищет в предыдущих дирикториях
/** ищет в последующих директориях
\? ищет любой спец.символ

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