Question

I have what appears to me a complex text file that include around 300 entries. I have no idea how to go about parsing this file to get the output I want. Each of my network users has an entry in the file. So in the text file, each user name starts with:

USER:martha
USER:Othello
USER:darwin

Underneath each user entry in the file there are a host of information I require , but one user can have one entry and another can have multiple entries. Here is the example of 3 such entries

USER:martha
    POSITION: 170.198.82.13 [VLT(304394),PT(FULL)]
            CLIENT: jcrm19.1.p2ps -258-
            ACCESSPOINT: 170.198.82.13/net
            APPLICATION: 91

USER:othello 
    POSITION: 170.198.80.212 [VLT(307571),PT(FULL)]
            CLIENT: jcrm15.1.p2ps -258-
            ACCESSPOINT: 170.198.80.212/net
            APPLICATION: 256

            CLIENT: jcrm15.1.p2ps -258-
            ACCESSPOINT: 170.198.80.212/net
            APPLICATION: 256

    POSITION: 170.198.80.209 [VLT(306561),PT(FULL)]
            CLIENT: jcrm14.1.p2ps -258-
            ACCESSPOINT: 170.198.80.209/net
            APPLICATION: 256

            CLIENT: pwrm14.1.p2ps -258-
            ACCESSPOINT: 170.198.80.209/net
            APPLICATION: 256

            CLIENT: pwrm14.1.p2ps -258-
            ACCESSPOINT: 170.198.80.209/net
            APPLICATION: 256


USER:darwin
    POSITION: 170.198.19.102 [VLT(297987),PT(FULL)]
            CLIENT: jcrm16.1.p2ps -258-
            ACCESSPOINT: 170.198.19.102/net
            APPLICATION: 91

The final output should look as follow:

USER        Position           Client     Application 

Martha      170.198.82.13       jcrm19      91
Othello     170.198.80.212      jcrm15      256
Othello     170.198.80.209      jcrm14      256
Martin      170.198.19.102      jcrm16      91

I have some experience with arrays and I could grep out some of the information and assign to variable and print them. But I just don't know how to read the information into the arrays as the entries under each "USER" since they are of different length and content.

So How do I read USER: martha and then jump to user:othello ? Also, under user:othello there are two "Positions" that I need to grab. I just don't know how to put the content I'm looking for into array variables or regular variables. I never had to parse a file that had different length and content data for each use. Not sure how many lines I have to read before I start reading and assigning values to array or values for the next user> Can you provide some hints or perhaps a piece of code that I can start with ?

Thanks

Was it helpful?

Solution 2

I haven't got my Mac to hand so this is untested...

awk -F: '/^USER:/{u=$2} /POSITION:/{p=$2} /CLIENT:/{c=$2} /APPLICATION:/{print u,p,c,$2}' yourfile

OTHER TIPS

Using awk with column:

awk -F '[: ]+' 'BEGIN{print "USER", "Position", "Client", "Application"} 
  $1=="USER"{u=$2} $2=="POSITION"{p=$3}$2=="CLIENT"{c=$3}
  $2=="APPLICATION"&&p{print u, p, c, $3; p=""}' file | column -t

USER     Position        Client         Application
martha   170.198.82.13   jcrm19.1.p2ps  91
othello  170.198.80.212  jcrm15.1.p2ps  256
othello  170.198.80.209  jcrm14.1.p2ps  256
darwin   170.198.19.102  jcrm16.1.p2ps  91
awk -v RS="" -F'[:\n ]*' '/^USER/{u=$2}
 /POSI/{p=/^USER/?$4:$3
 for(i=1;i<=NF;i++)
     if($i=="CLIENT"){sub(/\..*/,"",$(i+1))
                      print u,p,$(i+1),$NF;break}}' file

the output without header:

martha 170.198.82.13 jcrm19 91
othello 170.198.80.212 jcrm15 256
othello 170.198.80.209 jcrm14 256
darwin 170.198.19.102 jcrm16 91

you could add header and pipe to column -t to gain better format

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top