Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

awk pattern to multiple vlookup

Tags:

awk

vlookup

I have following file:

    Diameter link name:      ztesbydra1-ocs-1        
    Diameter link state:     fine 
    TCP/SCTP link name:      ztesbydra1-ocs-1   
    TCP/SCTP link state:     active 
    VRF name:                GxGyGa
    Local IP/port number:    172.31.210.243/3401     
    Dest IP/port number:     172.31.240.67/3401    
    Diameter link location:  STU/1/1   
    
    
    Diameter link name:      ztesbydra1-ocs-2        
    Diameter link state:     fine 
    TCP/SCTP link name:      ztesbydra1-ocs-2   
    TCP/SCTP link state:     active 
    VRF name:                GxGyGa
    Local IP/port number:    172.31.210.244/3402     
    Dest IP/port number:     172.31.240.67/3402    
    Diameter link location:  STU/1/2   
    
    
    Diameter link name:      ztesbydra1-ocs-3        
    Diameter link state:     fine 
    TCP/SCTP link name:      ztesbydra1-ocs-3   
    TCP/SCTP link state:     active 
    VRF name:                GxGyGa
    Local IP/port number:    172.31.210.243/3403     
    Dest IP/port number:     172.31.240.67/3403    
    Diameter link location:  STU/1/3   
    
    
    Diameter link name:      ztesbydra1-ocs-4        
    Diameter link state:     fine 
    TCP/SCTP link name:      ztesbydra1-ocs-4   
    TCP/SCTP link state:     active 
    VRF name:                GxGyGa
    Local IP/port number:    172.31.210.244/3404     
    Dest IP/port number:     172.31.240.67/3404    
    Diameter link location:  STU/1/1   
    
    
    Diameter link name:      ztejktdra1-ocs-1        
    Diameter link state:     fine 
    TCP/SCTP link name:      ztejktdra1-ocs-1   
    TCP/SCTP link state:     active 
    VRF name:                GxGyGa
    Local IP/port number:    172.31.210.243/2401     
    Dest IP/port number:     172.31.216.67/2401    
    Diameter link location:  STU/1/2   
    
    
    Diameter link name:      ztejktdra1-ocs-2        
    Diameter link state:     fine 
    TCP/SCTP link name:      ztejktdra1-ocs-2   
    TCP/SCTP link state:     active 
    VRF name:                GxGyGa
    Local IP/port number:    172.31.210.244/2402     
    Dest IP/port number:     172.31.216.67/2402    
    Diameter link location:  STU/1/3   


Diameter link name:      ztejktdra1-ocs-3        
Diameter link state:     fine 
TCP/SCTP link name:      ztejktdra1-ocs-3   
TCP/SCTP link state:     active 
VRF name:                GxGyGa
Local IP/port number:    172.31.210.243/2403     
Dest IP/port number:     172.31.216.67/2403    
Diameter link location:  STU/1/1   


Diameter link name:      ztejktdra1-ocs-4        
Diameter link state:     fine 
TCP/SCTP link name:      ztejktdra1-ocs-4   
TCP/SCTP link state:     active 
VRF name:                GxGyGa
Local IP/port number:    172.31.210.244/2404     
Dest IP/port number:     172.31.216.67/2404    
Diameter link location:  STU/1/2

I want to make it as csv format for easy readable format.

enter image description here

Bellow is my script:

$ cat parsing.sh       
#!/bin/bash`
awk '
 BEGIN { RS="\n";FS="[:/]"; OFS="," }
 NR==1 { print "PGW,Peer,IP PGW,Port PGW,IP DRA,Port DRA,vrf,Protocol" }
 /Diameter link name/ { tm = sprintf("%s",$2) }
 /Local IP/ { pl  = sprintf("%s,%s",$3,$4) }
 /Dest IP/  { printf("%s,%s,%s,%s\n",tm,pl,$3,$4) }
 ' 30.txt

but the result is not as I expected:

$ ./parsing.sh 
PGW,Peer,IP PGW,Port PGW,IP DRA,Port DRA,vrf,Protocol
,     172.31.216.66,2414

please help me, why output is not as I am expected.

Thanks,

Budi

like image 411
Wolverine adamantium Avatar asked Jun 07 '26 07:06

Wolverine adamantium


2 Answers

Whenever you have tag-value pairs in your input I find it best to first create an array to hold the tag to value mappings (f[] below) and then you can print, compare, change whatever values you like just by referring to their tags (names), e.g. using any POSIX awk:

$ cat tst.awk
BEGIN { OFS="," }
NF {
    gsub(/^[[:space:]]+|[[:space:]]+$/,"")
    tag = val = $0
    sub(/[[:space:]]*:.*/,"",tag)
    sub(/[^:]+:[[:space:]]*/,"",val)
    f[tag] = val
    next
}
tag != "" {
    print                               \
        f["Diameter link name"],        \
        f["Diameter link state"],       \
        f["TCP/SCTP link name"],        \
        f["TCP/SCTP link state"],       \
        f["VRF name"],                  \
        f["Local IP/port number"],      \
        f["Dest IP/port number"],       \
        f["Diameter link location"]
    delete f
    tag = ""
}

$ awk -f tst.awk file
ztesbydra1-ocs-1,fine,ztesbydra1-ocs-1,active,GxGyGa,172.31.210.243/3401,172.31.240.67/3401,STU/1/1
ztesbydra1-ocs-2,fine,ztesbydra1-ocs-2,active,GxGyGa,172.31.210.244/3402,172.31.240.67/3402,STU/1/2
ztesbydra1-ocs-3,fine,ztesbydra1-ocs-3,active,GxGyGa,172.31.210.243/3403,172.31.240.67/3403,STU/1/3
ztesbydra1-ocs-4,fine,ztesbydra1-ocs-4,active,GxGyGa,172.31.210.244/3404,172.31.240.67/3404,STU/1/1
ztejktdra1-ocs-1,fine,ztejktdra1-ocs-1,active,GxGyGa,172.31.210.243/2401,172.31.216.67/2401,STU/1/2
ztejktdra1-ocs-2,fine,ztejktdra1-ocs-2,active,GxGyGa,172.31.210.244/2402,172.31.216.67/2402,STU/1/3
ztejktdra1-ocs-3,fine,ztejktdra1-ocs-3,active,GxGyGa,172.31.210.243/2403,172.31.216.67/2403,STU/1/1

Change the print statement to print whatever parts of whatever fields you like in whatever order you like.

Or if you just want to print all the values as CSV with the tags as headers then:

$ cat tst.awk
BEGIN { OFS="," }
NF {
    gsub(/^[[:space:]]+|[[:space:]]+$/,"")
    tag = val = $0
    sub(/[[:space:]]*:.*/,"",tag)
    sub(/[^:]+:[[:space:]]*/,"",val)
    f[tag] = val
    tags[++numTags] = tag
    next
}
numTags {
    if ( !doneHdr++ ) {
        for ( i=1; i<=numTags; i++ ) {
            tag = tags[i]
            printf "%s%s", tag, (i<numTags ? OFS : ORS)
        }
    }
    for ( i=1; i<=numTags; i++ ) {
        tag = tags[i]
        printf "%s%s", f[tag], (i<numTags ? OFS : ORS)
    }
    numTags = 0
}

$ awk -f tst.awk file
Diameter link name,Diameter link state,TCP/SCTP link name,TCP/SCTP link state,VRF name,Local IP/port number,Dest IP/port number,Diameter link location
ztesbydra1-ocs-1,fine,ztesbydra1-ocs-1,active,GxGyGa,172.31.210.243/3401,172.31.240.67/3401,STU/1/1
ztesbydra1-ocs-2,fine,ztesbydra1-ocs-2,active,GxGyGa,172.31.210.244/3402,172.31.240.67/3402,STU/1/2
ztesbydra1-ocs-3,fine,ztesbydra1-ocs-3,active,GxGyGa,172.31.210.243/3403,172.31.240.67/3403,STU/1/3
ztesbydra1-ocs-4,fine,ztesbydra1-ocs-4,active,GxGyGa,172.31.210.244/3404,172.31.240.67/3404,STU/1/1
ztejktdra1-ocs-1,fine,ztejktdra1-ocs-1,active,GxGyGa,172.31.210.243/2401,172.31.216.67/2401,STU/1/2
ztejktdra1-ocs-2,fine,ztejktdra1-ocs-2,active,GxGyGa,172.31.210.244/2402,172.31.216.67/2402,STU/1/3
ztejktdra1-ocs-3,fine,ztejktdra1-ocs-3,active,GxGyGa,172.31.210.243/2403,172.31.216.67/2403,STU/1/1
like image 67
Ed Morton Avatar answered Jun 10 '26 18:06

Ed Morton


Using GNU AWK

$ awk -F':' '
    /Diameter link name/,/Diameter link location/{
        gsub(/^ *| *$/,"",$2)
        gsub(/\//,",",$2) 
        a[i+=1]=$2; 
        if(i==8){ 
            printf "%s,%s,%s,%s\n",a[1],a[6],a[7],a[5]
            i=0
        }
    }
' file
ztesbydra1-ocs-1,172.31.210.243,3401,172.31.240.67,3401,GxGyGa
ztesbydra1-ocs-2,172.31.210.244,3402,172.31.240.67,3402,GxGyGa
ztesbydra1-ocs-3,172.31.210.243,3403,172.31.240.67,3403,GxGyGa
ztesbydra1-ocs-4,172.31.210.244,3404,172.31.240.67,3404,GxGyGa
ztejktdra1-ocs-1,172.31.210.243,2401,172.31.216.67,2401,GxGyGa
ztejktdra1-ocs-2,172.31.210.244,2402,172.31.216.67,2402,GxGyGa
ztejktdra1-ocs-3,172.31.210.243,2403,172.31.216.67,2403,GxGyGa
ztejktdra1-ocs-4,172.31.210.244,2404,172.31.216.67,2404,GxGyGa
like image 35
ufopilot Avatar answered Jun 10 '26 19:06

ufopilot