Небольшой пример использования регулярных выражений grep

Не так давно перед моим хорошим знакомым встала задача: есть файл с настройками DHCP в виде:

host h1{
hardwareethernet 00:40:d1:64:ee:80;
fixed-address 10.167.13.121;
}
....
host h1000{
hardwareethernet 00:13:77:3d:46:6f;
fixed-address 10.167.12.104;
}

Ему нужно было привести его к виду:

host h1{hardware ethernet 00:40:d1:64:ee:80;fixed-address 10.167.13.121;}
....
host h1000{hardware ethernet 00:13:77:3d:46:6f;fixed-address 10.167.12.104;}

и сделать таблицу с MAC-адресами и соответствующими им IP. Если первая задача решается с помощью обычной замены символов, то вытаскивать тысячу адресов вручную, чтобы составить таблицу - то еще удовольствие, поэтому он попросил написать для этого простенький скриптик. Я решил сделать это средствами bash для простоты. MAC- и IP-адрес будем выдергивать из файла с помощью утилиты grep. Многие знают, для чего она нужна, но не все знают, что grep поддерживает регулярные выражения. При этом никаких средств Perl устанавливать или использовать не нужно. Основная команда, которой мы будем пользоваться, выглядит так:

grep -E -o '[0-9,aAbBcCdDeEfF]{1,2}(\:[0-9,aAbBcCdDeEfF;]{1,3}){5}'

Ключ -E означает, что grep будет использовать регулярное выражение, -o заставляет утилиту выводить только то, что совпало из строки, а не всю строку, как обычно. Теперь о формате самого выражения. [0-9,aAbBcCdDeEfF] - это перечисление символов, которые будем искать. В MAC-адрес входят цифры от 0 до 9 и большие и малые буквы до F. Далее в фигурных скобках указываем, что будем использовать две позиции. В круглых скобках вновь описываем выражение для остальных октетов MAC-адреса, а также указываем, что разделителем будет двоеточие - \:. Также добавляем точку с запятой и ищем в трех позициях. Потом указываем, что будем повторять поиск еще 5 раз - {5}. Таким образом мы составили паттерн для поиска MAC-адреса.
Теперь команда

cat /etc/dhcp3/dhcpd.conf | grep -E -o '[0-9,aAbBcCdDeEfF]{1,2}(\:[0-9,aAbBcCdDeEfF;]{1,3}){5}'

выведет нам все физические адреса из конфига DHCP.

Для поиска IP регулярное выражение аналогичное - [0-9]{1,2}(\.[0-9,;]{1,4}){3}. Думаю, почему оно такое, понятно.

Теперь выводим физические адреса в файл mac:

comm="[0-9,aAbBcCdDeEfF]{1,2}(\:[0-9,aAbBcCdDeEfF;]{1,3}){5}"

for i in $(cat /etc/dhcp3/dhcpd.conf | grep -E -o $comm)
do
echo $i > mac
done

А IP-адресавфайлip:

comm="[0-9]{1,2}(\.[0-9,;]{1,4}){3}"

for i in $(cat /etc/dhcp3/dhcpd.conf | grep -E -o $comm)
do
echo $i > ip
done

Теперь готовим данные в нужном формате для конфига DHCP:

c=1
d=1

hn="host h"
fa=" fixed-address "
hd="{ hardware ethernet "
cl=" }"

for i in $(cat mac)
do
d=1
for j in $(cat ip)
do

if test $c = $d
then
echo $hn$c$hd$i$fa$j$cl>dhcpd.conf
fi

d=$((d+1))
done

c=$((c+1))
done

Теперь в файле dhcpd.conf нужно только прописать настройки для данной группы адресов, то есть указать DNS-серверы, шлюз, время аренды и т.д. Чтобы сделать файл с таблицей MAC-IP, достаточно немного изменить формат вывода данных — и дело в шляпе. Как видите, в Linux консоль - это мощная штука.

Алексей Голованов, Минск 2010


Компьютерная газета. Статья была опубликована в номере 29 за 2010 год в рубрике программирование

©1997-2024 Компьютерная газета