【发布时间】:2020-09-11 12:31:24
【问题描述】:
我正在尝试调试一个 perl 脚本来解析包含 IPv6 地址和端口详细信息的表上的 snmpwalk 输出。
snmpwalk命令在shell上的执行结果如下:
[root@newton log]# /usr/bin/snmpwalk -v 2c -c secret localhost SNMP-TARGET-MIB::snmpTargetAddrTAddress
SNMP-TARGET-MIB::snmpTargetAddrTAddress.'2' = Hex-STRING: FD 22 1A 16 0E D3 01 00 00 00 00 00 00 10 00 41
00 A2
perl 脚本尝试获取 snmpTargetAddrTAddress. 之后的值 -> 即 2,然后尝试获取 Hex-STRING 之后的值。它在代码中使用以下正则表达式
@buf = `$snmpwalk $address_oid`;
foreach (@buf) {
if (/snmpTargetAddrTAddress\.'(.+?)' = Hex-STRING: ([\w ]+)/)
my $name = $1;
my $rest= $2;
log_msg( LOG_CRIT, "Found IP $rest for $name" );
}
$1 等于2
$2 等于 FD 22 1A 16 0E D3 01 00 00 00 00 00 00 10 00 41
但我也需要出现在 shell 换行符中的值 00 A2。
我尝试了在线工具 - https://regex101.com/。它提供的正则表达式为 ([\w ]+)(\n[\w ]+)。但是在代码中使用时,我没有得到任何输出。
以下不输出任何内容
if (/snmpTargetAddrTAddress\.'(.+?)' = Hex-STRING: ([\w ]+)(\n[\w ]+)/
我做错了什么?在线工具中的上述表达式会产生结果。如果我需要在 shell 输出中获取出现在换行符中的字符,我还可以使用哪些其他正则表达式?
@GMB 建议后的代码:
if(/snmpTargetAddrTAddress\.'(.+?)' = Hex-STRING: ([\w\s\n]+)/) {
my $name = $1;
my $rest = $2;
log_msg( LOG_CRIT, "Found IP $rest for $name" );
}
看到的日志是:
" Found IP FD 22 1A 16 0E D3 01 00 00 00 00 00 00 10 00 41 for 2"
更新:根据来自@zdim 和@ikegami 的cmets,我错误地假设“00 A2”将成为第二次迭代本身的一部分。由于它们出现在第三行,因此它们出现在 foreach 的第三次迭代中
【问题讨论】:
-
展示你如何得到这个字符串会很有帮助......你是否有机会在反引号下运行命令(并分配给一个标量)? (那些
00 A2真的用这个命令在单独的一行出现吗?) -
重新更新,您正在匹配
$_。它实际上包含整个文本还是仅包含第一行? -
conf_params.trap_target_ip6 @zdim,ikegami。我的错 。在不检查 $_.这似乎不包含整个文本。我已经更新了描述中的代码。我在运行命令后使用
foreach。在循环的第三次迭代中可以看到“00 A2”!。 -
好吧,这样更好。那么,
@buff中有什么,你能证明一下吗?什么“第三次迭代”——问题开头显示的在 shell 中运行的示例,总共显示了两行? -
如果想要的 "rest" 确实是输出中的所有其余部分,那么您可以分配给一个标量 (
my $ret = qx(...);),在这种情况下,反引号返回一个多行字符串,然后使用 GMB 的答案。 (或者加入行my $ret = join '', @buff;并在上面使用它。)