Официальная возможность получить лицензионный софт бесплатно.
Giveaway of the Day
Это не реклама!

Щелкните для получения прогноза по Биробиджану


Показаны сообщения с ярлыком regexp. Показать все сообщения
Показаны сообщения с ярлыком regexp. Показать все сообщения

среда, 4 августа 2021 г.

WMIC и серийный номер APC ИБП

 Обект WMI Win32_Battery имеет много интересных свойств, одно из них - deviceId. Но ИБП от APC пихают в это поле всё подряд - от серийного номера до версий firmware.

Возникла задача: выделить только серийный номер, при этом остальные свойства, которые wmic возвращает в виде непрерывной строки, поля в которой разделяются вертикальной чертой (|) остались на месте.

В конце концов родилось вот такое:

wmicc.sh ИМЯ_КОМПА|tail -n +3 |sed -r "s/([0-9][A-Z][0-9]{4}[A-Z][0-9]{5})[^|]*/\1/g" |datamash transpose -t \| |column -t -s \|

wmicc.sh - это скрипт-обертка, передающий wmic-у вспомогательные параметры - авторизацию и т.п., а так же параметры отбора.

tail обрезает первые 2 строки, в которых содержится ненужный мне мусор.

datamash transpose преобразует последовательные строки в столбцы

column придает этим столбцам красивую ширину

А самое интересное делает sed. В поле deviceId текст выглядит примерно так:

1A2152Z12345  American Power ConversionBack-UPS XS 650CI FW:892.R2.I USB FW:R2

Первое алфавитно-цифровое сочетание и есть серийный номер ИБП, причем 2 цифры сразу после первой буквы (A21) - это год выпуска (пример серийника выше - условный, так что год в нём 2021). Но вот всё остальное до конца строки мне ни к чему.

Поля, как уже сказано, отделяются друг от друга вертикальной чертой, поэтому задача была оставить только серийник, убрав всё остальное до границы поля. Поэтому регэксп читается примерно так:

  1. найти сочетание вида ЦБЦЦЦЦБЦЦЦЦЦ (Ц - цифра, Б - буква), обозначить его как "группа 1"
  2. в той же строке сразу после этой группы искать любое количество любых символов кроме вертикальной черты
  3. заменить найденное в п.п.1 и 2 на то, что находится в "группа 1"
  4. Профит!
$ echo "1A2152Z12345  American Power ConversionBack-UPS XS 650CI FW:892.R2.I USB FW:R2|" |sed -r "s/([0-9][A-Z][0-9]{4}[A-Z][0-9]{5})[^|]*/\1/g"

1A2152Z12345|

Хитрость была в том, что я далеко не сразу понял, как именно указать, что нужно искать всё до ближайшего разделителя полей. Для выполнения таких подстановок ключ -r обязателен, иначе sed ругается.

четверг, 28 марта 2019 г.

Немного о regexp в MySQL

Таблетка для памяти:

Есть служба, компы в которой могут иметь имена от cnt30150 до cnt30149z.
Шаблон для тех, кто понимает:

cnt30[0-9]{3}[0-9a-z]{1}

При этом только 3 цифры после cnt30 есть собственно номер компа, а последний знак - дополнительный индекс, который может повторяться у разных компов.

Для отбора компов вышеупомянутой службы из базы OCS Inventory используем такое регулярное выражение:

select id,name from hardware where name rlike "cnt301(3[5-9]{1}|4[0-9]{1})."

То есть, выбираем компы, имена которых начинаются с cnt301, после чего идет либо тройка, за которой должна следовать цифра от 5 до 9, либо четверка, после которой должна быть цифра от 0 до 9, и заканчивается это одним любым символом.

Дополнительно стоит заметить, что для rlike (он же - regexp) шаблон указывается в двойных кавычках, как это делается для имени поля, а не в апострофах, как обычная строка.

Конечно, можно было задать этот же диапазон как:

select id,name from hardware where name >= 'cnt301350' and name <= 'cnt30149z'

что тоже правильно, но ведь это не так красиво, а?

понедельник, 11 августа 2014 г.

sed: чистка логов

Сошел с ума SARG: после настройки авторизации в сквиде через AD в логах стали появляться записи вида:

что-то-там ... домен\имя_пользователя ...

SARG, видя такое безобразие, в итоговом отчете всем пользователям присваивает имя "домен", из-за чего отчет становится нечитаемым.

Пришлось думать, как почистить логи прежде чем скормить SARG-у

cat лог|sed 's/домен\\//'|sed 's/.*TCP_DENIED.*$//'|sed '/^$/d'

первый sed убирает из лога упоминания про "домен\"
второй убирает все строки, где пользователь получил отказ в доступе
третий убирает оставшиеся пустые строки.

Наверное, будет логичнее совместить второй и третий и поставить их перед первым, чтобы не делать лишние замены "домен\" в строках, которые всё равно будут удалены.

Да, более правильной и быстрой оказалась такая конструкция:

cat лог|sed '/^.*TCP_DENIED.*$/d'|sed 's/[дД][оО][мМ][еЕ][нН]\\//'

Возможно, удалось бы совместить обе замены в одну, но уже лень.

пятница, 23 августа 2013 г.

AWK: regexp - проверка email

Емайл должен начинаться с буквы, допустимые знаки - алфавит, цифры, подчеркивание, точка, минус.

(параметр a1 передается через "awk -v a1=$1" или вроде того - проверяем емайл, переданный в командной строке)

BEGIN {print "start"}

{
if (a1 !~ /^[a-zA-Z]+([a-zA-Z]|\_|\-|\.|[0-9])+@мой\.домен\.ru/)
    {print "'" a1 "'"  ":not email" }
else
    {print  "'" a1 "'" ":looks like email" }
exit}

END {print "finish"}

вторник, 22 января 2013 г.

Я уже писал о составных поисках "или-или" в grep. Но или греп тогда был другой, или я что-то не то написал, но конструкция

grep "либо_то|либо_это"


не работает.

Правильный вариант:

grep -E "либо_то|либо_это"

например:

tail -f  /var/log/syslog | grep -E "named|dhcpd"

отфильтрует строки, в которых есть хотя бы одно упоминание любого из демонов, что очень удобно при решении проблем с DNS.

четверг, 7 июня 2012 г.

Сложный поиск с grep

Для красноглазых гуру это будет "фи!", а мне в самый раз - заметочка на память.

Понадобилось мне фильтровать системный лог. Ну, чего проще:

grep "искомое" имя_лога

А если по двум критериям?

grep "искомое1" имя_лога|grep "искомое2"

Угу. Вот только этот вариант работает по логике AND, и если хотя бы одного из искомых не будет, то в выдачу ничего не попадет. Однако, чукча не только писатель, но и читатель. Пришлось курить маны и хауту. Подсказали мне про egrep, но он штатно есть не на всех системах.

Правильный ответ со штатным grep:

grep ["искомое1|искомое2|...|искомоеN"]