2015-01-31 7 views
-1

Мне нужно, чтобы все маки были основаны на списке, который соответствует контрольной точке и поставщикам cisco. Я делаю «show ip arp» на Cisco Router, улавливаю вывод arp и сохраняю файл. Теперь, мне нужно проверить по очереди, какие у меня есть macs.Использование переменной между regexp внутри foreach

Чтобы быть точным, мне нужно сопоставить только строки, содержащие адреса MAC-адресов поставщиков Cisco и Checkpoint. Для этого я должен получить IP-адрес, первые шестнадцатеричные цифры, точку и еще две шестнадцатеричные цифры, чтобы определить поставщика mac, например (001c.7f или e02f.6d), и распечатать эту строку в файле. После этого мне нужно сравнить «IP-ARP.txt» и «MAC-ADDRESS.txt» (этот последний содержит полнофункциональных поставщиков mac-адресов). Если мой результат совпадает, сохраните эту строку в другом файле.

Вот часть файлов:

IP-ARP.txt

Internet 172.20.14.12   0 001c.7f41.186e ARPA 

Internet 172.20.14.13   57 001c.7f41.074e ARPA 

Internet 172.20.14.14   0 0200.5ebd.e17d ARPA 

Internet 172.20.19.11   - 7081.050f.9402 ARPA 

Internet 172.20.19.12   54 7cad.7499.e602 ARPA 

Internet 172.20.19.13   7 e02f.6d14.c1bf ARPA 

Internet 172.20.19.14   104 e02f.6d15.1d7f ARPA 

MAC-ADDRESS.txt

001c.7f

001c.ab

001b .de

001b.ff

001c.cd

001c.de

e02f.6c

e02f.7c

Спасибо заранее-х!

+0

@Bohemian Done! Я перефразирую и удаляю свои комментарии. Благодаря! –

ответ

1

(снова обновляется за счет изменения спецификации)

То, что мы имеем здесь список идентификации строк (адрес частей OUI MAC записаны в виде фрагментов строку адреса MAC) и список строк данных, необходимо проверить на этот список.

Мое решение использует пакет fileutil из библиотеки Tcl. Это не совсем необходимо, поскольку вы можете использовать стандартные команды Tcl, но это значительно упрощает сценарий.

package require fileutil 

Определите некоторые имена файлов для использования.

set filename(macaddr) MAC-ADDRESS.txt 
set filename(iparp) IP-ARP.txt 
set filename(output) output.txt 

Если идентифицирующий список строк может быть изменена, вы можете прочитать его из файла каждый раз вы запустите скрипт:

set idlist [::fileutil::cat $filename(macaddr)] 

Или, если эти адреса редко меняются, вы можете просто Аппаратно скопируйте его в свой скрипт и отредактируйте при необходимости:

set idlist {001c.7f 001c.ab 001b.de 001b.ff 001c.cd 001c.de e02f.6c e02f.7c} 

Установите содержимое выходного файла в пустую строку.

::fileutil::writeFile $filename(output) {} 

Для выбора строки в файле IP-ARP.txt, которые соответствуют любому из этих адресов, существует несколько способов, чтобы пройти через него.Мое предложение - использовать команду fileutil::foreachLine. Основной вызов, как это:

::fileutil::foreachLine varName filename script 

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

Сценарий вызывает команду, которая соответствует строкам id с помощью команды string match. Вместо этого можно было бы использовать команду regexp, но я думаю, что в этом случае это совершенно необязательно. Каждая строка в файле IP-ARP.txt либо пустой, либо правильный список Tcl с пятью элементами, где MAC-адрес является четвертым. Кроме того, вторым элементом является номер ip, и только те, которые начинаются с 172, должны использоваться. Это означает, что команда соответствия может быть записана следующим образом:

proc matchid {idlist line} { 
    set ipAddr [lindex $line 1] 
    set macAddr [lindex $line 3] 

    if {[string match 172* $ipAddr]} { 
     foreach id $idlist { 
      if {[string match $id* $macAddr]} { 
       return "$ipAddr $macAddr\n" 
      } 
     } 
    } 
} 

(Matching адреса IP-таким образом, работает только если адрес в десятичном формате десятичного: если он может быть в любой другой форме IP-модуле Tcllib следует использовать для его соответствия.)

Результатом команды является либо строка, содержащая IP-адрес и MAC-адрес, если соответствующая строка, либо пустая строка, если это не так.

Теперь можно пройти содержимое файла IP-ARP.txt. Для каждой строки сопоставляйте содержимое с идентификационным списком и получаете либо выходную строку, либо пустую строку. Если строка не пуста, добавьте ее в выходной файл.

::fileutil::foreachLine line $filename(iparp) { 
    set res [matchid $idlist $line] 

    if {$res ne {}} { 
     ::fileutil::appendToFile $filename(output) $res 
    } 
} 

И все. Полная программа:


package require fileutil 

set filename(macaddr) MAC-ADDRESS.txt 
set filename(iparp) IP-ARP.txt 
set filename(output) output.txt 

set idlist [::fileutil::cat $filename(macaddr)] 

::fileutil::writeFile $filename(output) {} 

proc matchid {idlist line} { 
    set ipAddr [lindex $line 1] 
    set macAddr [lindex $line 3] 

    if {[string match 172* $ipAddr]} { 
     foreach id $idlist { 
      if {[string match $id* $macAddr]} { 
       return "$ipAddr $macAddr\n" 
      } 
     } 
    } 
} 

::fileutil::foreachLine line $filename(iparp) { 
    set res [matchid $idlist $line] 

    if {$res ne {}} { 
     ::fileutil::appendToFile $filename(output) $res 
    } 
} 

Документация для Tcllib fileutil module

Документация: foreach, if, lindex, package, proc, set, string

(Примечание: «Hoodiecrow », упомянутый в комментарии это я, я что Ник ранее)

+1

Вы хотите 'read -nonewline', иначе последняя итерация цикла foreach будет выполнена с пустым $ a –

+0

@Hoodiecrow еще раз! Я попробую это завтра в GMT -3. После, я публикую результаты! –

+0

@ Хозяйство сделано! Я перефразирую и удаляю свои комментарии. Благодаря! –

0

Учитывая частичные МАС-адрес (в виде «XXXX.XX») в переменной $mac, чтобы соответствовать строке, содержащей MAC-адрес, начиная с этим значением:.

^.*\b$mac[0-9a-f]{2}\.[0-9a-f]{4}\b.*$ 

Если ваш язык соответствует линии, которые содержат шаблон, вы можете опустить обертывание:

\b$mac[0-9a-f]{2}\.[0-9a-f]{4}\b 
+0

ITYM '\ y':' \ b' соответствует обратному пространству в синтаксисе Tcl re. Эти шаблоны также потерпят неудачу, если будут совпадать шестнадцатеричные числа с верхним регистром A-F. Даже с ограничениями слов '\ y' эти шаблоны будут соответствовать второй группе MAC-адреса. –

0

на основании ответа Hoodiecrow, я сделал это:

set Ouilist { 0000.0c 0001.42 0001.43 0001.63 0001.64 ... } 

set Macs1 [open "IP-ARP.txt" r] 

foreach a [split [read -nonewline $Macs1] \n] { 

set macAddr [lindex $a 3] 

set IP [lindex $a 1] 

    if { [regexp {(172)\.([0-9]+)\.([0-9]+)\.([0-9]+)} $IP RealIP] } { 

     regexp {([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])\.([0-9a-f])([0-9a-f])} $macAddr OuiPart 
     if { $OuiPart in $Ouilist } { 
      puts "$RealIP $macAddr\r 
     } 

    } 

Таким образом, я получаю все ips, которые начинаются с 172 и mac-адресов, которые являются поставщиками Cisco и Checkpoint.

+0

Извините, но * ouch *. Вы все еще используете эту команду 'regexp', и вы действительно не должны. Я обновлю свой ответ, чтобы отразить изменения спецификации. –

 Смежные вопросы

  • Нет связанных вопросов^_^