我有一个配置文件,其中包含重复的行组(但组中的行数不同(,我想将其组合成单个csv行,以便于导入数据库。(数据库结构灵活(。
# Example:
lag 1
description "LAG-1 GOES TO LAG-2"
port 1/2/1
port 1/2/2
port 3/2/3
lacp active administrative-key 32770
exit
lag 10
description "REMOVED-LAG-10-0.0.0.0"
port 4/1/1
port 5/1/1
lacp active administrative-key 32771
exit
lag 11
description "REMOVED-LAG-11-4.4.4.4"
port 5/1/2
lacp active administrative-key 32772
exit
我最终需要为"lag"和"exit"之间的每个块使用逗号分隔的行,如下所示:
1,"LAG 1 GOES TO LAG-2",32770,1/2/3
1,"LAG 1 GOES TO LAG-2",32770,1/2/2
1,"LAG 1 GOES TO LAG-2",32770,3/2/3
10,"REMOVED-LAG-10-0.0.0.0",32771,4/1/1
10,"REMOVED-LAG-10-0.0.0.0",32771,5/1/1
11,"REMOVED-LAG-11-4.4.4.4",32772,5/1/2
然后我会导入到这样的表中:
lag-id | description | key | port
我尝试了在这里找到的各种尴尬的单行代码,例如:
awk -v RS="lag" 'NR>1{$1=$1; print RS, $0}'
但这似乎垂直压缩了线条,所以我最终得到了
exit 3/2/3 "LAG 1 GOES TO LAG-2"
exit 4/2/3 "LAG 10 GOES TO LAG-3"
exit 4/1/1 "LAG 11 GOES TO LAG-21"
编辑:略微更新了配置,描述可能有两次LAG-x数字。 编辑 2:更新了添加 lacp 值以获取每个 csv 行的管理密钥。
你能试试下面的吗?
awk -v OFS="," '
{
gsub(/r/,"")
sub(/^ +/,"")
}
/lag/{
ind=$2
next
}
/description/ && match($0,/".*"/){
des=substr($0,RSTART,RLENGTH)
next
}
/port/{
print ind,des,$2
}
' Input_file
如果您的字符串可能是大写或小写字母或混合,那么您可以在上面的代码中添加一个带有IGNORECASE=1
的BEGIN
部分,然后在任何情况下它都应该匹配字符串。
说明:以下仅用于说明目的,请参阅上面的完整代码。
-v OFS=","
所有行的输出字段分隔符设置为逗号。
gsub(/r/,"")
根据 OP 的评论将 \r 控制 m 个字符全局替换为 NULL 他们在那里。
sub(/^ +/,"")
在此处将行的初始空间替换为 NULL。
/lag/{Ind=$2;next}
具有字符串滞后的搜索行并接下来创建值为 $2 的变量 Ind 将从这里开始跳过所有进一步的语句。
/description...../
查找包含字符串描述的行,然后使用 awk 的匹配函数在同一行中查找从"
到"
的正则表达式。将此匹配的正则表达式值保存在名为 desc 的变量中,接下来将跳过此处的所有进一步语句。
/port/...
寻找具有字符串端口的行,然后根据 OP 的要求在此处打印 ind,des,$2 的值。
$ cat tst.awk
BEGIN { OFS="," }
{
tag = $1
sub(/^[[:space:]]*[^[:space:]]+[[:space:]]*/,"")
vals[++numVals] = $0
}
tag == "exit" {
for (valNr=3; valNr<numVals; valNr++) {
print vals[1], vals[2], vals[valNr]
}
numVals = 0
}
$ awk -f tst.awk file
1,"LAG-1 GOES TO LAG-2",1/2/1
1,"LAG-1 GOES TO LAG-2",1/2/2
1,"LAG-1 GOES TO LAG-2",3/2/3
10,"REMOVED-LAG-10-0.0.0.0",4/1/1
10,"REMOVED-LAG-10-0.0.0.0",5/1/1
11,"REMOVED-LAG-11-4.4.4.4",5/1/2
另一个尴尬:
awk '$1~/lag/{l=$2;next}
$1~/description/{d=substr($0,index($0,"""));next}
$1~/port/{print l,d,$2}
' OFS=, file
前 2 个语句将第二个字段分别放入lag
和description
关键字的l
d
和变量中。
最后一条语句打印 2 个变量和与port
关键字关联的第二个字段。