Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Хочу рассказать об одной утилите для поиска, которая очень сильно упрощает жизнь. Когда я попадаю на сервер и мне надо что-то поискать я первым делом проверяю установлен ли ack. Эта утилита является прекрасной заменой grep, а также в какой-то мере find и wc. Почему не grep? Ack имеет более приятные настройки из коробки, более человеко-читаемые опции, perl регулярки и систему конфигов. Если вы любите(приходится) искать через терминал, то вам однозначно стоит ее попробовать.
Базовые возможности
Ack по умолчанию рекурсивен, а писать меньше опций всегда хорошо.
Мы можем использовать флаг -w, чтобы сказать утилите искать экземпляр нашего шаблона, окруженный границами слов(пробельными символами, слэшом и т.д.).
ack -w mysql
Ack поддерживает поиск по типу файлов. Например, найдем версию модуля в json файлах.
ack --json '"version":\s+"\d+\.\d+\.\d+"'
Полный список поддерживаемых типов файлов можно посмотреть с помощью:
ack --help-types
Зачастую надо посчитать сколько раз фраза встречается в лог файле, например, чтобы понять как много данных обработал скрипт.
Считаем сколько раз process встречается в файле test.log, не учитывая регистр (-i).
Мы можем посчитать вхождения не просто в одном конкретном файле, а в группе. Доработаем предыдущий поиск слова mysql: посчитаем кол-во вхождений слов (-с) в *.js файлах(--js), исключив файлы в которых ничего не найдено (-h) и просуммировав итог.
# выведем на экран все вхождения
ack --js -w mysql
# считаем общую сумму вхождений
ack --js -wch mysql
Кроме того, мы можем получить развернутый отчет по кол-ву вхождений в каждый файл с помощью (-l)
ack --js -w -cl mysql
Если вам необходим дополнительный контекст для поиcка, можно попросить ack
показать строки до (-B) и после (-A) найденного выражения. Для этого надо указать после опции кол-во строк, которое необходимо показать.
# 2 строки до
ack --js --column -B 2 "query.once\('" ./lib/
# 2 строки после
ack --js --column -A 2 "query.once\('" . /lib/
А если нужно и то и другое, то используйте (-С)
ack --js --column -C 2 "query.once\('" ./lib/
Имеется также опция(-v) для инвертирования поиска, т.е показывать строки в которых нет заданного шаблона.
Регулярные выражение
Ack в отличие от grep использует Perl совместимые выражения.
Для меня это большой плюс, не приходится запоминать отдельный синтаксис для регулярок.
ack 'var\s+add\s+'
Более сложный пример
ack '\*\s+\[v\d+\.\d+\.\d+\]'
Зачастую хочется в результатах оставить только то, что совпадает с шаблоном. Здесь поможет опция --output (-o)
ack -o '\*\s+\[v\d+\.\d+\.\d+\]'
Ко всему прочему, с помощью круглых скобок мы можем выделить найденную часть и обратиться к ней в output через переменную $[номер группы]. Например,
ack --output='version is $1' '\*\s+\[v(\d+\.\d+\.\d+)\]'
Ack имеет полезные опции --range-start и --range-end. Они помогают, когда
данные хранятся не одной строкой, а в многострочном виде.
Например, есть файл с sql кодом
Извлечем названия колонок. Началом блока будет строка начинающаяся на SELECT, а концом строка начинающаяся на FROM.
ack --range-start ^SELECT --range-end ^FROM 't\d+\.' ./test.sql
Если в поисковом выражении участвуют специальные символы такие как точка, круглая скобка и другие, то для того чтобы их не экранировать с помощью \, можно использовать опцию -Q.
# Поиск с экранированием
ack --json 'mysql\.'
# Поиск без экранирования
ack --json -Q mysql.
Работа с файлами
Получить список файлов с определенным расширением
ack -f --js
Найти все js файлы имя которых начинается с P*, используя опцию(-g).
ack -g --js '\/Pa.+.js$'
Конфигурация
Утилита имеет свой конфиг файл. Можно иметь как глобальный конфиг для пользователя(~/.ackrc), так и локальный для конкретной папки (в папке необходимо создать файл .ackrc).
Большинство опций, которые прописываются в конфиги можно и руками прописывать при вызове. Разберем несколько из них.
Игнорировать папку при поиске
--ignore-dir=dist
Добавим кастомный тип файла --vue.
--type-add=vue:ext:js,vue
Теперь можно использовать опцию --vue, для поиска в файлах .vue. Например: ack --vue App.
При этом можно указать список расширений для этой опции. Например, тут при использовании --vue будут обработаны и .js файлы.
Игнорировать файлы, например, минифицированные *.min.js
--ignore-file=match:/\.min\.js$/
Установка
CentOS
yum update -y && yum install ack -y
Ubuntu
apt-get update -y && apt-get install ack-grep -y
Mac OS
brew update && brew install ack
Установка с сайта
curl https://beyondgrep.com/ack-v3.3.1 > ~/bin/ack && chmod 0755 ~/bin/ack
Плагины для редакторов:
- Sublime Text
- VSCode
- Vim
Заключение
Это далеко не все возможности. Полный список функций можно посмотреть, выполнив:
ack –-help
# или
ack --man
Утилита ack позволяет сделать поиск в терминале удобнее и гибче. А с помощью pipeline (ack -C 10 hello | ack world) можно создать мощный комбайн по поиску и фильтрации данных в файловой системе и в самих файлах.