(由于规格变化再次更新)
我们这里有一个识别字符串列表(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"
}
}
}
}
(以这种方式匹配 ip 地址仅在地址为点分十进制形式时才有效:如果它可以是任何其他形式,则应使用 Tcllib ip 模块来匹配它。)
如果该行匹配,则该命令的结果是包含 ip 地址和 MAC 地址的行,如果不匹配,则为空字符串。
现在让我们遍历IP-ARP.txt
文件的内容。对于每一行,将内容与 id 列表进行匹配,并获取输出字符串或空字符串。如果字符串不为空,请将其附加到输出文件。
::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 模块的文档
文档:foreach、if、lindex、package、proc、set、string
(注意:评论中提到的“Hoodiecrow”是我,我之前用过那个昵称。)