我的脚本提供以下outout,我需要将其转换为json结构。通过Perl或AIX上的其他转换是我想要的路径的一部分。现在我正在阅读大量文档并进行试验(=迄今为止没有成功)..
感谢任何帮助/指示: - )
TEST STATUS FAIL REASON
---- ------ -----------
Security Profile PASS
Group Check FAIL Errors detected in group definition files
User Check FAIL Errors detected in user definition files
Service hostmibd FAIL Active
Service aixmibd FAIL Active
Subserver shell FAIL Active
Subserver kshell FAIL Active
Subserver login FAIL Active
Subserver exec FAIL Active
Subserver bootps FAIL Active
Subserver tftp FAIL Active
Subserver ntalk FAIL Active
SNMP version FAIL snmpdv3ne
SNMP community PASS
SSHD status PASS
答案 0 :(得分:3)
该程序从DATA
文件句柄读取样本数据,并从中构建JSON数据结构。
通过检查标题下方的连字符行来确定每列中数据的位置。使用unpack
从每一行提取字段以及从这些位置派生的模板。
JSON
模块用于通过将结果转换为Perl数据结构来测试结果,结果使用Data::Dump
转储。
支持嵌入数据中的双引号。
希望您能够修改此代码以从您想要的输入文件而不是DATA
中读取,并使用生成的JSON数据执行任何操作。
use strict;
use warnings;
use 5.014; # For non-destructive tr/// and s///
my $headers = <DATA>;
my $dashes = <DATA>;
my @offsets;
push @offsets, $-[0] while $dashes =~ /-+/g;
my @widths = map { $offsets[$_]-$offsets[$_-1] } 1 .. $#offsets;
push @widths, '*';
my $unpack = join ' ', map "A$_", @widths;
my @headers = map { lc =~ tr/ /_/r } unpack $unpack, $headers;
my @lines;
while (<DATA>) {
next unless /\S/;
my @fields = map s/"/\\"/gr, unpack $unpack, $_;
push @lines, ' {' . join(', ', map qq{"$headers[$_]":"$fields[$_]"}, 0 .. $#fields). '}';
}
my $json = "[\n" . join(",\n", @lines) . "\n]\n";
print $json, "\n\n";
use JSON;
use Data::Dump;
dd from_json $json;
__DATA__
TEST STATUS FAIL REASON
---- ------ -----------
Security Profile PASS
Group Check FAIL Errors detected in group definition files
User Check FAIL Errors detected in user definition files
Service hostmibd FAIL Active
Service aixmibd FAIL Active
Subserver shell FAIL Active
Subserver kshell FAIL Active
Subserver login FAIL Active
Subserver exec FAIL Active
Subserver bootps FAIL Active
Subserver tftp FAIL Active
Subserver ntalk FAIL Active
SNMP version FAIL snmpdv3ne
SNMP community PASS
SSHD status PASS
输出JSON
[
{"test":"Security Profile", "status":" PASS", "fail_reason":""},
{"test":"Group Check", "status":"FAIL", "fail_reason":"Errors detected in group definition files"},
{"test":"User Check", "status":"FAIL", "fail_reason":"Errors detected in user definition files"},
{"test":"Service hostmibd", "status":"FAIL", "fail_reason":"Active"},
{"test":"Service aixmibd", "status":"FAIL", "fail_reason":"Active"},
{"test":"Subserver shell", "status":"FAIL", "fail_reason":"Active"},
{"test":"Subserver kshell", "status":"FAIL", "fail_reason":"Active"},
{"test":"Subserver login", "status":"FAIL", "fail_reason":"Active"},
{"test":"Subserver exec", "status":"FAIL", "fail_reason":"Active"},
{"test":"Subserver bootps", "status":"FAIL", "fail_reason":"Active"},
{"test":"Subserver tftp", "status":"FAIL", "fail_reason":"Active"},
{"test":"Subserver ntalk", "status":"FAIL", "fail_reason":"Active"},
{"test":"SNMP version", "status":"FAIL", "fail_reason":"snmpdv3ne"},
{"test":"SNMP community", "status":"PASS", "fail_reason":""},
{"test":"SSHD status", "status":"PASS", "fail_reason":""}
]
输出Perl数据
[
{ fail_reason => "", status => " PASS", test => "Security Profile" },
{
fail_reason => "Errors detected in group definition files",
status => "FAIL",
test => "Group Check",
},
{
fail_reason => "Errors detected in user definition files",
status => "FAIL",
test => "User Check",
},
{ fail_reason => "Active", status => "FAIL", test => "Service hostmibd" },
{ fail_reason => "Active", status => "FAIL", test => "Service aixmibd" },
{ fail_reason => "Active", status => "FAIL", test => "Subserver shell" },
{ fail_reason => "Active", status => "FAIL", test => "Subserver kshell" },
{ fail_reason => "Active", status => "FAIL", test => "Subserver login" },
{ fail_reason => "Active", status => "FAIL", test => "Subserver exec" },
{ fail_reason => "Active", status => "FAIL", test => "Subserver bootps" },
{ fail_reason => "Active", status => "FAIL", test => "Subserver tftp" },
{ fail_reason => "Active", status => "FAIL", test => "Subserver ntalk" },
{ fail_reason => "snmpdv3ne", status => "FAIL", test => "SNMP version" },
{ fail_reason => "", status => "PASS", test => "SNMP community" },
{ fail_reason => "", status => "PASS", test => "SSHD status" },
]
答案 1 :(得分:0)
固定长度数据始终是unpack
的好兆头。
您需要JSON模块进行转换。该程序从STDIN读取并将文件作为参数。
#!/usr/bin/env perl
use warnings;
use strict;
use JSON;
my @names = qw<test status fail_reason>;
my @return;
while(<>){
next if $. < 3; # skip the header
chomp;
my (%obj);
@obj{@names} = grep {$_} unpack 'A32A16A*';
push @return, \%obj;
}
print encode_json \@return;
输出:
[{"status":"PASS","fail_reason":null,"test":"Security Profile"},{"status":"FAIL","test":"Group Check","fail_reason":"Errors detected in group definition files"},{"test":"User Check","fail_reason":"Errors detected in user definition files","status":"FAIL"},{"test":"Service hostmibd","fail_reason":"Active","status":"FAIL"},{"status":"FAIL","test":"Service aixmibd","fail_reason":"Active"},{"test":"Subserver shell","fail_reason":"Active","status":"FAIL"},{"status":"FAIL","fail_reason":"Active","test":"Subserver kshell"},{"status":"FAIL","test":"Subserver login","fail_reason":"Active"},{"fail_reason":"Active","test":"Subserver exec","status":"FAIL"},{"status":"FAIL","test":"Subserver bootps","fail_reason":"Active"},{"fail_reason":"Active","test":"Subserver tftp","status":"FAIL"},{"fail_reason":"Active","test":"Subserver ntalk","status":"FAIL"},{"fail_reason":"snmpdv3ne","test":"SNMP version","status":"FAIL"},{"test":"SNMP community","fail_reason":null,"status":"PASS"},{"test":"SSHD status","fail_reason":null,"status":"PASS"}]
<强>编辑强>:
使用此行可以排除空字段(如果状态为通过,则不会出现失败原因)。
delete $obj{$_} foreach grep {$obj{$_} eq '' or not defined $obj{$_} keys %obj;
如果你有更多这样的文件有不同的字段大小,这里有一个提取字段长度的版本:
my (@return, @names, $head_line, $pack_template);
while (<>) {
chomp;
if ($. == 1) { # set the header line
$head_line = $_;
}
elsif($. == 2){
# extract the lengths from the second line
my @lengths = map(length, (/(-+\s*)/g));
$lengths[-1]= '*'; # replace the last length with * as a catch rest
$pack_template = join '', map {"A$_"} @lengths;
@names = unpack $pack_template, $head_line;
} else {
my (%obj);
@obj{@names} = unpack $pack_template;
push @return, \%obj;
}
}