Script to match a pattern and print only the pattern and after that

Hi,

I am writing a shell script to parse some files, and gather data.
The data in the files is displayed as below.

.......xyz: [1234] abz: [8987]......
.......xyz: [12312] abz: [adfa].....

I have tried using awk and cut, bu the position of these values keep changing, so I can use awk and split it into columns.
The value before the ":' is always constant, the value in the brackets only keep changing.
I need an option which prints in the following manner based on what is being grepped.

if xyz: is grepped it should print

xyz: [1234]
xyz: [12312]

(OR)

if abz: is grepped it should print

abz: [8987]
abz: [adfa]

Please help

Thanks

Something like this:

$ cat file
abc :[2345] xyz: [1234] abz: [8987]
cde :[256] xyz: [12312] abz: [adfa]

$ awk -F"[: ]" -v va="abz" '{for(i=1;i<=NF;i++) { if(c==1&&length($i)>1) {c=0;print $i} ; if($i==va) {c=1} }}' file
[8987]
[adfa]

You could also use grep:

$ grep -oE "xyz: \[[^]]+\]" file
xyz: [1234]
xyz: [12312]
1 Like

Thank you both the solutions work,

I have one more question. I also need to be able to compare the values in the same line for example

.......xyz: [1234] abz: [1234]......qrt: [2312]....
.......xyz: [1231] abz: [2414]......qrt: [1231]...

it should be a one liner and it should be able to compare the value in the brackets for "xyz:" and "abz:" and if it is the samee then it should print "qrt: [2312]"

In the above lines the output should be only "qrt: [2312]" as that is the only line with the matching value in the bracket of "xyz:" and "abz:".

The positions of this variable keep changing in the same line, so I cannot use the divide by columns.

I'm curious: why should it be a one-liner? Is there some length limit? Because, technically, you can convert any large, multi-line awk script into a one liner by simply deleting the newline bytes.

Regards,
Alister

What should the script output if qrt: does not match the other two? Are these abc: xyz: qrt: values input parameters or hard-coded into script? Can you should some example input, script parameters and required output?

this condition is part of a much larger script, Initially I have used the following condition, bu there have been changes int he file format where the values are not specific to a column, so this is not working.

awk '$2!=$5{print $9}'

I hope this info helps.

Thanks

---------- Post updated 02-28-13 at 12:51 PM ---------- Previous update was 02-27-13 at 01:40 PM ----------

can some one please help me with the second question?

Thanks

Try

awk     'NR==1  {n = split (items, IT)}                 # put the items to search for into array IT
                {for (i=1; i<NF; i++)                   # check every single field in actual line
                   for (j=1; j<=n; j++)                 # against the items wanted
                     if ($i == IT[j]) VL[j]=$(++i)      # if found, register value (= next field) in array VL, and skip check on value
                }
         VL[1]==VL[2]   {print VL[3]}                   # if values of first two items match, print value of third
        ' items="xyz: abz: qrt:" file
[2312]

Can you provide me with a one liner, for the above solution, i tried to modify it to a oneliner, but wasn't working. Please help

Thanks

Can you provide me with a one liner, for the above solution, 

Is it a home work? If not,why you want it in a one liner?

You are interested in the solution (or)number of lines in the code?

Please justify.

I need a one liner because it is part of a bigger script as I have mentioned. I am not sure what do you mean by homework. I am writing this script to gather a lot of different variables, and this is just one of the variable.

A solution and the number of lines in the code is also equally important to me as I will be filtering a lot of other parameters before i come to this part of comparison, and also do a lot more filtering and calculation.

Earlier when the position of the variables in the log files weren't changing so i used to use a simple awk comparison like below,

awk '$2!=$5{print $9}'

I am not an expert in awk, so I am asking help on this.

And finally sorry for starting another thread, I wasn't sure if it has to be one question in each thread, so I started a new one.

Most of the time, I search and try for solutions from the existing threads, but i couldn't find anything close to my problem and I really need some help in getting this solution.

Thanks

Can the position of the "qrt" is only after "xyz" and "abz" or it can be before that?

For example:If input is:

.......xyz: [1234] qrt:  [1234]....... abz: [2312]....
.......xyz: [1231] abz: [2414]......qrt: [1231]...

What is the output expected ?

If input is:

.......xyz: [1234] abz:  [1234]....... qrt: [2312]......xcd: [2234]

What is the output expected ?

The position of "qrt", "xyz" and "abc" would change. It can be in any order.

if the input is

.......xyz: [1234] qrt:  [1234]....... abz: [2312]....
.......xyz: [1231] abz: [2414]......qrt: [1231]...

then the output should be null, as I want the comparison of the value in the bracket of only xyz and abz. and print qrt only if it is the same.
In your example the values in the brackets of xyz and abz are not equal so, it should not return anything

if the input is

.......xyz: [1234] abz:  [1234]....... qrt: [2312]......xcd: [2234]

then the output should be qrt:[2312]. As the values int he brackets of abz is equal to the value in the brackets of xyz.

The strings "xyz:", "abz:" and "qrt:" always remain the same only the values in the bracket keep changing.

I hope this makes it more clear.

Thanks

The solution offered above works perfectly on all examples you provided so far. Put it into a function if you aim for readability of the main script.
BTW, even if sensibly (!) collapsed to a one liner, it will work ...

The code below works ok to me.Even the code provided by RudiC should work perfectly.

For a complex query you can't reduce the code much!..

awk -v va1="abz:" -v va2="xyz:"  -v  va3="qrt:" '
{ for(i=1;i<=NF;i++) { if($i==va1) v1=$(i+1) ; if($i==va2) v2=$(i+1); if($i==va3) v3=$(i+1) }
if (v1==v2) { print va3""v3 }
}' file