Print part of an array or file and sort in a shell

I have a text file as follows

1 : dis conn(*) type(CONN) all where(UOWLOG ne '') AMQ8276: Display Connection details. CONN(AE1CA9572C47D822) EXTCONN(414D51434D5147575032202020202020) TYPE(CONN) PID(9098) TID(503215) APPLDESC(WebSphere MQ Channel) APPLTAG(WebSphere MQ Client for Java) APPLTYPE(USER) ASTATE(NONE) CHANNEL(ABIS.CLIENT) CLIENTID( ) CONNAME(101.54.151.80) CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_FASTPATH_BINDING) USERID(malth) UOWLOG(S0599315.LOG) UOWSTDA(2016-08-16) UOWSTTI(11.06.38) UOWLOGDA(2016-08-16) UOWLOGTI(11.06.38) URTYPE(QMGR) EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[]) QMURID(0.190537069) UOWSTATE(ACTIVE) AMQ8276: Display Connection details. CONN(AE1CA957D787F429) EXTCONN(414D51434D5147575032202020202020) TYPE(CONN) PID(28292) TID(1519092) APPLDESC(WebSphere MQ Channel) APPLTAG(WebSphere MQ Client for Java) APPLTYPE(USER) ASTATE(NONE) CHANNEL(SB.CLIENT) CLIENTID( ) CONNAME(101.54.151.119) CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_FASTPATH_BINDING) USERID(sbp) UOWLOG(S0599317.LOG) UOWSTDA(2016-08-16) UOWSTTI(11.07.38) UOWLOGDA(2016-08-16) UOWLOGTI(11.07.38) URTYPE(QMGR) EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[]) QMURID(0.190520281) UOWSTATE(ACTIVE) AMQ8276: Display Connection details. CONN(2CC7AE57CE8E6221) EXTCONN(414D51434D5147575032202020202020) TYPE(CONN) PID(22400) TID(647335) APPLDESC(WebSphere MQ Channel) APPLTAG(WebSphere MQ Client for Java) APPLTYPE(USER) ASTATE(NONE) CHANNEL(U90785.CBM.CLIENT) CLIENTID( ) CONNAME(101.54.163.37) CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_FASTPATH_BINDING) USERID(machlth) UOWLOG(S0599317.LOG) UOWSTDA(2016-08-16) UOWSTTI(11.07.40) UOWLOGDA(2016-08-16) UOWLOGTI(11.07.40) URTYPE(QMGR) EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[]) QMURID(0.190574800) UOWSTATE(ACTIVE) AMQ8276: Display Connection details. CONN(2CC7AE571BF0B721) EXTCONN(414D51434D5147575032202020202020) TYPE(CONN) PID(22210) TID(1069968) APPLDESC(WebSphere MQ Channel) APPLTAG(WebSphere MQ Client for Java) APPLTYPE(USER) ASTATE(NONE) CHANNEL(APP.CLIENT) CLIENTID( ) CONNAME(101.54.163.127) CONNOPTS(MQCNO_HANDLE_SHARE_BLOCK,MQCNO_FASTPATH_BINDING) USERID(apsp) UOWLOG(S0599317.LOG) UOWSTDA(2016-08-16) UOWSTTI(11.07.29) UOWLOGDA(2016-08-16) UOWLOGTI(11.07.29) URTYPE(QMGR) EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[]) 

Now I want my output to show

 ABIS.CLIENT,101.54.151.80,malth,S0599315.LOG,11.06.38 APP.CLIENT,101.54.163.127,apsp,S0599317.LOG,11.07.29 SB.CLIENT,101.54.151.119,sbp,S0599317.LOG,11.07.38 CBM.CLIENT,101.54.163.37,machlth,S0599317.LOG,11.07.40 

so basically, get the channel name, conname, userid, UUOWLOG and UOWLOGTI and sort it all at the end of UOWLOGTI. I am trying to do this in a shell.

I tried using awk , but cannot get the desired result.

cat UOWLOG.txt|awk -vRS="" 'BEGIN{printf ""}/\<'AMQ8276'\>/^CHANNEL{printf $0 RT}' I get errors when I try to use different options in awk. Please, help.

0
source share
4 answers

everything can be done in awk , but maybe easier with a tool chain

 $ grep -oP '(CHANNEL|CONNAME|USERID|UOWLOG|UOWLOGTI)\(.*?\)' file | awk -F'[()]' '{ORS=NR%5?",":RS; print $2}' | sort -t, -k5 ABIS.CLIENT,101.54.151.80,malth,S0599315.LOG,11.06.38 APP.CLIENT,101.54.163.127,apsp,S0599317.LOG,11.07.29 SB.CLIENT,101.54.151.119,sbp,S0599317.LOG,11.07.38 U90785.CBM.CLIENT,101.54.163.37,machlth,S0599317.LOG,11.07.40 
+2
source

My solution is similar to @karakfa, but makes no assumptions for field order:

 $ grep -o '^\w\+:\|\w\+[(][^)]\+[)]' file | awk -F '[()]' -v OFS="," 'function printValues() { if ("CHANNEL" in p) { print p["CHANNEL"], p["CONNAME"], p["USERID"], p["UOWLOG"], p["UOWLOGTI"] } } /^\w+:/ { printValues(); delete p; next } { p[$1] = $2 } END { printValues() }' | sort -t, -k 5 

What I am doing is creating an associative array for each "record", and then only printing the necessary fields.

+1
source

My lil bit dirty gnu awk solution:

 $ awk -v RS="AMQ" 'NR>1{ print gensub(/.*CHANNEL\(([^)]+).*CONNAME\(([^)]+).*USERID\(([^)]+).*UOWLOG\(([^)]+).*UOWLOGTI\(([^)]+).*/,"\\1,\\2,\\3,\\4,\\5","1")}' file | sort -t "," -k5 ABIS.CLIENT,101.54.151.80,malth,S0599315.LOG,11.06.38 APP.CLIENT,101.54.163.127,apsp,S0599317.LOG,11.07.29 SB.CLIENT,101.54.151.119,sbp,S0599317.LOG,11.07.38 U90785.CBM.CLIENT,101.54.163.37,machlth,S0599317.LOG,11.07.40 
+1
source

I do not know, but the accepted answer does not give the indicated output for the channel "CBM.CLIENT", and all the answers are still intensive single-line. When the conversion is so complicated, I like the whole script, so I can see that.

 #! /usr/bin/awk -f function Print() { OFS = "," print line["CHANNEL"], line["CONNAME"], line["USERID"], \ line["UOWLOG"], line["UOWLOGTI"] delete line } /Display Connection details[.]$/ { if( length(line) ) { Print() } next } $1 == "CHANNEL" { line[$1] = $2 if( 3 == split( $2, channel, /[.]/ ) ) { line[$1] = channel[2] "." channel[3] } next } { line[$1] = $2 } END { Print() } 

The method is to build an associative array of all elements foo (bar), and output interesting bits in an obvious way. Regular expressions are simple and initial assumptions are relaxed: there is no dependence on the type of field and very little dependence on formatting.

He relies on a little preprocessing to put each key / value pair on his own line and post-processing to sort the output. Call as:

 $ cat f.sh #! /bin/sh sed -E 's/^ +//; s/ +$//g; s/ +/\ /g' $1 | awk -F '[:()]' -f script.awk | sort -t, -k5 $ ./f.sh dat ABIS.CLIENT,101.54.151.80,malth,S0599315.LOG,11.06.38 APP.CLIENT,101.54.163.127,apsp,S0599317.LOG,11.07.29 SB.CLIENT,101.54.151.119,sbp,S0599317.LOG,11.07.38 CBM.CLIENT,101.54.163.37,machlth,S0599317.LOG,11.07.40 

In the comments, OP mentions printing only lines that match a specific criterion. This is easy to add to this Print() function, and is easy to understand later.

+1
source

Source: https://habr.com/ru/post/1263187/


All Articles