来源看起来像这样:
test/snmp/result/08-28-2016_12-30/AAAAA/hostname01_192.168.1.1
161/udp open snmp
| snmp-brute:
| comstring1 - Valid credentials
|_ comstring2 - Valid credentials
test/snmp/result/08-28-2016_12-30/AAAAA/hostname02_192.168.1.2
161/udp open snmp
| snmp-brute:
| comstring1 - Valid credentials
|_ comstring1 - Valid credentials
如何解析上面的文本,使其变为:
08-28-2016_12-30|AAAAA|hostname01|192.168.1.1|comstring1-Valid credentials -- comstring1 - Valid credentials
08-28-2016_12-30|AAAAA|hostname02|192.168.1.2|comstring1-Valid credentials -- comstring1 - Valid credentials
主要问题是代码无法根据字符“|”进行分组或“|_”,我更改了很多代码但没有成功,例如:
awk '{ORS=($0 !~ "_"?FS:RS)}1'
答案1
您的脚本不必对记录分隔符或字段分隔符执行任何特殊操作。给定示例输入和输出,脚本只需查找四种行类型中的两种,即
test/snmp/result/08-28-2016_12-30/AAAAA/hostname01_192.168.1.1
(这是大多用/
字符分隔),以及
| comstring1 - Valid credentials
可以通过正则表达式进行匹配。
该脚本必须匹配第一个线型,例如,
/^.*\/.*\/.*\// {
split($0, "/", fields);
# ...more work needed :-)
并使用split
根据字符将其切入数组/
, 和sub
,substr
并index
切掉该行的其余部分(来自单独的主机名和IP地址"hostname01_192.168.1.1"
)。
完成后,它会为您提供变量,printf
在从第二行类型中提取消息后,这些变量将被带入完成中。这样做可能需要 30 行脚本
答案2
解决方案在TXR。该文件data
逐字包含问题中的数据。reformat.txr
包含这个:
@(collect)
test/snmp/result/@date/@label/@{host}_@ipaddr
@port/udp open snmp
| snmp-brute:@(skip)
@ (collect :gap 0)
| @string - @val
@ (end)
|_ @endstring - @endval
@ (merge string string endstring)
@ (merge val val endval)
@(end)
@(output)
@ (repeat)
@date|@label|@host|@ipaddr|@(rep)@string - @val -- @(last)@string - @val@(end)
@ (end)
@(end)
跑步:
$ txr reformat.txr data
08-28-2016_12-30|AAAAA|hostname01|192.168.1.1|comstring1 - Valid credentials -- comstring2 - Valid credentials
08-28-2016_12-30|AAAAA|hostname02|192.168.1.2|comstring1 - Valid credentials -- comstring1 - Valid credentials
TXR 非常适合在结构松散的数据上进行文本提取,而无需投入大量工作,并且在结构发生变化或必须适应新案例等情况下也无需投入更多工作。
编写 TXR 提取作业通常首先将实际样本数据和输出复制并粘贴到文件中.txr
,然后通过添加捕获变量和指令来对其进行调整。工作脚本是从数据本身中产生的。
在生成的代码中数据的结构仍然或多或少是可识别的。
答案3
解决了 :)
awk '$0!~/(161|brute)/ {if ($0~/_/)ORS="\n"; else ORS="";print}'