billy19murahmi
billy19murahmi

Reputation: 35

printing after retrieving all the required fields using awk/sed/bash

Looking for the correct way to print in the required format using awk/sed/bash.

Consider a file (awk_test.txt) with the following content,

Checkpoint number: ckpt.123
value1: 10
value2: 10
Checkpoint number: ckpt.234
value1: 20
value2: 25

How to extract data from file and print it in the following format in a new line?

ckpt.123,10,10
ckpt.234,20,25

I tried with the following awk command, but doesn't print all.

awk < awk_test.txt '/ckpt/{a=$NF} /value1/{b=$NF} /value2/{c=$NF} END {printf "%s,%s,%s\n",a,b,c}'

Upvotes: 2

Views: 216

Answers (4)

LMC
LMC

Reputation: 12672

For GNU awk, Record Separator RS can be set to any regular expression, in this case, can be set to Checkpoint number. Field separator FS can be set to : or \n. This way lines are turned into fields.

gawk 'BEGIN{ RS="Checkpoint number" ; FS=": |\n"; OFS="," } { if(NR > 1){ print $2,$4,$6 }}' text.txt

Result:

ckpt.123,10,10
ckpt.234,20,25

NOTE: POSIX only supports a single character as RS. Thanks @EdMorton and @Rafael for your comments. I'm not used to think about portability.

Upvotes: 2

potong
potong

Reputation: 58430

This might work for you (GNU sed):

sed -r 's/.*: //;N;N;s/\n[^:]*: /,/g' file

Remove the labels and replace the newlines by comma's for lines modulo three.

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 203635

$ awk '/^Check/{if (NR>1) print rec; rec=$NF; next} {rec = rec "," $NF} END{print rec}' file
ckpt.123,10,10
ckpt.234,20,25

Upvotes: 2

Jonathan Leffler
Jonathan Leffler

Reputation: 753970

You only print data in the END block. Granted, you need the end block, but you also need to print when you get to a ckpt line and there's already some data accumulated. That leads to:

awk '/ckpt/   { if (a != "") printf "%s,%s,%s\n", a, b, c; a = $NF }
     /value1/ { b = $NF }
     /value2/ { c = $NF }
     END      { printf "%s,%s,%s\n", a, b, c }'

which, when used on your sample data, produces:

ckpt.123,10,10
ckpt.234,20,25

Or you could even use a function to encapsulate the printing:

awk 'function print_it() { printf "%s,%s,%s\n", a, b, c; }
     /ckpt/   { if (a != "") print_it(); a = $NF}
     /value1/ { b = $NF }
     /value2/ { c = $NF }
     END      { print_it() }'

This has the advantage of ensuring the same printing code is used in both places where the printing is required.

Upvotes: 1

Related Questions