I have a configuration file with repeating groups of lines (but different number of lines in a group) that I want to combine to single csv lines for easier importing to a database. (Database structure is flexible).
# 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
I ultimately need to end up with comma-separated lines for each block between "lag" and "exit", like this:
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
Then I would import to a table like this:
lag-id | description | key | port
I've tried various awk one-liners that I found here, such as:
awk -v RS="lag" 'NR>1{$1=$1; print RS, $0}'
but that seems to compress the lines vertically, so i end up with
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"
EDIT: Updated config slightly, description may have LAG-x numbers twice.
EDIT 2: Updated adding lacp values to get admin key to each csv line.
解决方案
Could you please try following.
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
In case your strings may be either capital or small letter or of mix then you could add a BEGIN section with IGNORECASE=1 in above code and it should match strings in any case then.
Explaination: Following is only for explanation purposes, refer complete code above please.
-v OFS="," setting output field separator as comma for all lines.
gsub(/\r/,"") globally substituting \r control m characters with NULL as per OP's comment they were there.
sub(/^ +/,"") Substituting initial space of line with NULL here.
/lag/{Ind=$2;next} searching line which had string lag in it and creating variable Ind whose value is $2 next will skip all further statements from here onwards.
/description...../ looking for line which has string description in it and then using match function of awk to look for regex from " till " in same line. Saving this matched regex value in variable named desc, next will skip all further statements from here.
/port/... looking for line which has string port in it and then printing value of ind,des,$2 here as per OP's requirement.