Эта статья демонстрирует использование программы nhrt для поиска и замены текста по регулярному выражению.
Допустим, у нас есть протокол работы некоторой программы:
11/13/2016 08:05 Error: data error '11/13/2016 08:03 userid=15' 11/14/2016 12:47 Warning: free disk space 10% 11/15/2016 22:21 Error: internal error
Протокол содержит даты событий в американском формате MM/DD/YYYY, и мне нужно заменить формат на российский DD.MM.YYYY или на универсальный YYYY-MM-DD.
Далее описаны параметры запуска nhrt и результаты выполнения. Ссылка, чтобы скачать эти примеры в виде командных файлов, находится в конце статьи.
Пример показывает использованием параметров:
- sre, search regular expression – поиск по регулярному выражению,
- ft, formatted text – замена по форматированному выражению, с использованием результатов поиска.
Замена формата даты на DD.MM.YYYY
Для этого нужно поменять местами числа месяца и дня месяца, а также заменить разделители.
Составляю регулярное выражение для поиска так, чтобы оно:
- искало число месяца и день месяца как отдельные компоненты – они потребуются по отдельности, чтобы можно было поменять их местами,
- искало только в начале строки – чтобы происходила замена только в дате события, но не в его описании.
Вот это регулярное выражение:
^(\d\d)/(\d\d)/
Выражение состоит из следующих частей:
- Крышечка в начале означает поиск только в начале строки.
- Первое вхождение
(\d\d)
означает две цифры, соответствующие номеру месяца в американском формате. - Наклонная черта – разделитель.
- Второе вхождение
(\d\d)
означает две цифры, соответствующие дню месяца в американском формате. - Опять разделитель.
Круглые скобки означают группу – найденный на этом месте текст будет доступен нам в выражении для замены.
Как работает поиск по этому выражению, на примере первой строки лог файла:
- Программа находит текст
11/13/
в начале строки (второе вхождение этого текста будет пропущено, так как задан поиск только в начале строки). - Две цифры 11 записываются в группу 1 и будут доступны под номером $1.
- Две цифры 13 записываются в группу 2 и будут доступны под номером $2.
Теперь, после того, как текст найден, составляю регулярное выражение для замены: оно строится очень просто – числа меняются местами, а разделители меняются на точки:
$2.$1.
В итоге, запуск программы с параметрами sre и ft:
nhrplc -sre:"^(\d\d)/(\d\d)/" -ft:"$2.$1." log.txt
даёт желаемый результат:
13.11.2016 08:05 Error: data error '11/13/2016 08:03 userid=15' 14.11.2016 12:47 Warning: free disk space 10% 15.11.2016 22:21 Error: internal error
Замена формата даты на YYYY-MM-DD
Пример отличается от предыдущего тем, что необходимо менять местами все три компонента даты.
Поэтому регулярное выражение будет содержать ещё и группу для номера года (4 цифры):
^(\d\d)/(\d\d)/(\d\d\d\d)
Выражение для замены расставляет все числа в нужном порядке и с дефисом в качестве разделителя:
$3-$2-$1
Строка запуска nhreplace:
nhrplc -sre:"^(\d\d)/(\d\d)/(\d\d\d\d)" -ft:"$3-$2-$1" log.txt
В результат выполнения, дата события отформатирована как требуется, при этом дата в описании не изменена:
2016-13-11 08:05 Error: data error '11/13/2016 08:03 userid=15' 2016-14-11 12:47 Warning: free disk space 10% 2016-15-11 22:21 Error: internal error
Замена формата даты в потоке stdin
Эти же замены могут быть сделаны в потоке stdin:
type log-s.txt | nhrplc -sre:"^(\d\d)/(\d\d)/(\d\d\d\d)" -ft:"$3-$2-$1" -notitle
Файлы для скачивания
Исходный файл и командные файлы этого примера доступны для скачивания по ссылке (ZIP).
Все CMD и JS/VBS скрипты (ZIP)