0

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

3 Answers 3

2

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
Sign up to request clarification or add additional context in comments.

3 Comments

This assumes that the fields will always be in the order in the sample. Which may be correct but should be pointed out.
hi thx .. I tried this. Yes the fields are always in this order. It works with the sample I provided and not with the text file I have .. Not sure why . I have to look at the log file again. Thx for quick response. will have to look later as I have to run to catch a train thx again!! anubhava
Sure let me know if you need further assistance.
0

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

3 Comments

OP just wants to pick the block with POSITION, yours prints entry for each block
@Kent Oh, yes, you are right, thank you. I'll leave him to choose between your and anubhava's answers.
Hi Mark. I tried your one liner and worked great. Not sure how it works , but it works. So thank you. I really have to understand how this position stuff work. also when I ran it against my original log file, it produced an additional columns of data .. but that's fine./
0
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

1 Comment

Hi Kent. Thanks for reply. Sorry I never got around this post. I tried ur code and it does not do anything. It produces no error and it does not produces any output?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.