我有一个像表格一样的日志
ge-1/0/0.0 up down inet 10.100.100.1/24
multiservice
ge-1/0/2.107 up up inet 10.187.132.193/27
10.187.132.194/27
multiservice
ge-1/1/4 up up
ge-1/1/5.0 up up inet 10.164.69.209/30
iso
mpls
multiservice
我们如何将其转换为格式化csv,如下所示:
ge-1/0/0.0,up,down,inet|multiservice,10.100.100.1/24
ge-1/0/2.107,up,up,inet|multiservice,"10.187.132.193/27,10.187.132.194/27"
ge-1/1/4,up,up
ge-1/1/5.0,up,up,inet|iso|mpls|multiservice,10.164.69.209/30
我尝试使用grep interfacename -A4,但它显示了其他界面信息。
答案 0 :(得分:3)
#!/bin/bash
show() {
[ "$ge" ] || return
[ "$add_quotes" ] && iprange="\"$iprange\""
out="$ge,$upd1,$upd2,$service,$iprange"
out="${out%%,}"
echo "${out%%,}"
}
while read line
do
case "$line" in
ge*)
show
read ge upd1 upd2 service iprange < <( echo "$line" )
add_quotes=
;;
[0-9]*)
iprange="$iprange,$line"
add_quotes=Y
;;
*)
service="$service|$line"
;;
esac
done
# Show last line
show
将您的示例数据作为stdin提供,此脚本将返回:
ge-1/0/0.0,up,down,inet|multiservice,10.100.100.1/24
ge-1/0/2.107,up,up,inet|multiservice,"10.187.132.193/27,10.187.132.194/27"
ge-1/1/4,up,up
ge-1/1/5.0,up,up,inet|iso|mpls|multiservice,10.164.69.209/30
工作原理:此脚本逐行读取stdin(while read line
)。然后将每一行分为三种类型之一:(a)新记录(即以“ge-”开头的行),(b)提供另一IP范围的连续记录(即以数字开头的记录) ),或(c)提供另一项服务的延续行(即以字母开头的记录)。依次采取这些案例:
(a)当该行包含新记录的开头时,表示前一记录已结束,因此我们使用show
函数将其打印出来。然后我们从新行读取我命名的五列:ge upd1 upd2 service iprange。并且,我们将add_quotes变量重置为空。
(b)当该行仅包含另一个IP范围时,我们将其添加到当前IP范围。根据问题中的示例,两个或多个IP范围的组合用逗号分隔并用引号括起来。因此,我们将add_quotes
设置为“Y”。
(c)当该行包含附加服务时,我们将其添加到服务变量中。根据问题中的示例,两个服务由竖线“|”分隔并且没有使用引号。
函数show
首先检查以确保通过检查ge
变量是否为空来显示要显示的记录。如果它为空,则执行return
语句,以便函数退出(返回)而不处理任何其他语句。如果$ge
非空,则函数将继续执行下一个语句,如果需要,它将在IP范围变量周围添加引号。然后它将变量与用逗号分隔的变量组合起来,删除尾随逗号(根据问题中的示例),并将结果发送到stdout。
答案 1 :(得分:1)
#!/usr/bin/gawk -f
BEGIN {
RS = "[^\n]*\n( [^\n]*\n)*"
OFS = ","
}
length(RT) > 0 {
$0 = RT # See: http://stackoverflow.com/a/11917783/27581
opts = ""
ips = ""
for (i = 4; i <= NF; ++i) {
if (isIP($i)) {
ips = append(ips, $i, ",")
} else {
opts = append(opts, $i, "|")
}
}
print $1, $2, $3, opts, "\"" ips "\""
}
function isIP(str) {
return str ~ /^[0-9]/
}
function append(list, val, separator) {
if (length(list) > 0) {
list = list separator
}
return list val
}
$ ./parselog.awk < log.txt
ge-1/0/0.0,up,down,inet|multiservice,"10.100.100.1/24"
ge-1/0/2.107,up,up,inet|multiservice,"10.187.132.193/27,10.187.132.194/27"
ge-1/1/4,up,up,,""
ge-1/1/5.0,up,up,inet|iso|mpls|multiservice,"10.164.69.209/30"