bash脚本如何将带有密钥的日志转换为csv
我有一个表格格式的日志bash脚本如何将带有密钥的日志转换为csv,bash,csv,Bash,Csv,我有一个表格格式的日志 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
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,但它无法显示其他界面信息
#!/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
工作原理:此脚本逐行读取标准数据(,同时读取行
)。然后将每一行分为三种类型:(a)新记录(即以“ge-”开头的行),(b)提供另一IP范围的连续记录(即以数字开头的记录),或(c)提供另一服务的连续记录(即以字母开头的记录)。依次处理这些案件:
(a) 当该行包含新记录的开始时,这意味着上一条记录已结束,因此我们使用show
功能将其打印出来。然后我们从新行中读到我命名的五列:ge upd1 upd2服务iprange。然后,我们将add_quotes变量重置为空
(b) 当该行仅包含另一个IP范围时,我们将其添加到当前IP范围。根据问题中的示例,两个或多个IP范围的组合用逗号分隔,并用引号括起来。因此,我们将add_quotes
设置为“Y”
(c) 当该行包含附加服务时,我们将其添加到服务变量中。根据问题中的示例,两个服务由竖条“|”分隔,不使用引号
函数show
首先通过检查ge
变量是否为非空来检查是否有要显示的记录。如果为空,则执行return
语句,使函数退出(返回),而不处理其任何其他语句。如果$ge
为非空,则函数将继续执行下一条语句,如果需要,该语句将在IP范围变量周围添加引号。然后,它将变量与分隔它们的逗号组合,删除尾随的逗号(如问题中的示例所示),并将结果发送给stdout
工作原理:此脚本逐行读取标准数据(,同时读取行
)。然后将每一行分为三种类型:(a)新记录(即以“ge-”开头的行),(b)提供另一IP范围的连续记录(即以数字开头的记录),或(c)提供另一服务的连续记录(即以字母开头的记录)。依次处理这些案件:
(a) 当该行包含新记录的开始时,这意味着上一条记录已结束,因此我们使用show
功能将其打印出来。然后我们从新行中读到我命名的五列:ge upd1 upd2服务iprange。然后,我们将add_quotes变量重置为空
(b) 当该行仅包含另一个IP范围时,我们将其添加到当前IP范围。根据问题中的示例,两个或多个IP范围的组合用逗号分隔,并用引号括起来。因此,我们将add_quotes
设置为“Y”
(c) 当该行包含附加服务时,我们将其添加到服务变量中。根据问题中的示例,两个服务由竖条“|”分隔,不使用引号
函数show
首先通过检查ge
变量是否为非空来检查是否有要显示的记录。如果为空,则执行return
语句,使函数退出(返回),而不处理其任何其他语句。如果$ge
为非空,则函数将继续执行下一条语句,如果需要,该语句将在IP范围变量周围添加引号。然后,它将变量与分隔变量的逗号组合,删除尾随的逗号(如问题中的示例所示),并将结果发送到stdout。parselog.awk
#/usr/bin/gawk-f
开始{
RS=“[^\n]*\n([^\n]*\n)*”
OFS=“,”
}
长度(RT)>0{
$0=RT#见:http://stackoverflow.com/a/11917783/27581
opts=“”
ips=“”
对于(i=4;i 0){
列表=列表分隔符
}
返回列表val
}
用法
$。/parselog.awk
parselog.awk
#/usr/bin/gawk-f
开始{
RS=“[^\n]*\n([^\n]*\n)*”
OFS=“,”
}
长度(RT)>0{
$0=RT#见:http://stackoverflow.com/a/11917783/27581
opts=“”
ips=“”
对于(i=4;i 0){
列表=列表分隔符
}
返回列表val
}
用法
$。/parselog.awk
大致上,我得到的是,这个脚本尝试逐行提取,当它遇到ge*接口时,它将处理,也将处理ip地址[0-9]。你能解释一下为什么我们使用add_quotes=Y吗?我添加了一个很长的解释。至于在IP范围周围添加引号的决定,它只是遵循问题中的示例输出:除了两个IP范围用逗号组合在一起时,IP范围周围没有引号。基本上,我得到的是,这个脚本尝试逐行提取,当它的meet ge*接口时,它将处理,也将处理IP地址[0-9]。你能解释一下为什么我们使用add_quotes=Y吗?我添加了一个很长的解释。至于在IP范围周围添加引号的决定,它只是按照问题中的示例输出:IP范围周围没有引号,除非两个IP范围用逗号组合在一起。
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
#!/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"