user5149108
user5149108

Reputation:

Print the consecutive 3 line at the pattern match

I have a huge file where i need to sort and merge 3 line which are having pattern match "vm" and need them into One Single Line, like Below

kfg-ap4 is the Server name , we can have it Only Once that will be nice while sorting .. I tried awk with getline but somehow i am missing to fit it ..

awk '/vm/ {printf $0 " ";getline; print $0}' mem_overc

**[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0**


[kfg-ap4] Executing task 'moc'
[kfg-ap4] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap4] out:
[kfg-ap4] out: We trust you have received the usual lecture from the local System
[kfg-ap4] out: Administrator. It usually boils down to these three things:
[kfg-ap4] out:
[kfg-ap4] out:     #1) Respect the privacy of others.
[kfg-ap4] out:     #2) Think before you type.
[kfg-ap4] out:     #3) With great power comes great responsibility.
[kfg-ap4] out:
[kfg-ap4] out: sudo password:
[kfg-ap4] out: vm.overcommit_memory = 0
[kfg-ap4] out: vm.overcommit_ratio = 50
[kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out:

======================================================================

Actual Data is as below and rest of the data is same except server names

[kfg-ap3] Executing task 'moc'
[kfg-ap3] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap3] out:
[kfg-ap3] out: We trust you have received the usual lecture from the local System
[kfg-ap3] out: Administrator. It usually boils down to these three things:
[kfg-ap3] out:
[kfg-ap3] out:     #1) Respect the privacy of others.
[kfg-ap3] out:     #2) Think before you type.
[kfg-ap3] out:     #3) With great power comes great responsibility.
[kfg-ap3] out:
[kfg-ap3] out: sudo password:
[kfg-ap3] out: vm.overcommit_memory = 0
[kfg-ap3] out: vm.overcommit_ratio = 50
[kfg-ap3] out: vm.nr_overcommit_hugepages = 0
[kfg-ap3] out:

[kfg-ap4] Executing task 'moc'
[kfg-ap4] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap4] out:
[kfg-ap4] out: We trust you have received the usual lecture from the local System
[kfg-ap4] out: Administrator. It usually boils down to these three things:
[kfg-ap4] out:
[kfg-ap4] out:     #1) Respect the privacy of others.
[kfg-ap4] out:     #2) Think before you type.
[kfg-ap4] out:     #3) With great power comes great responsibility.
[kfg-ap4] out:
[kfg-ap4] out: sudo password:
[kfg-ap4] out: vm.overcommit_memory = 0
[kfg-ap4] out: vm.overcommit_ratio = 50
[kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out:

Upvotes: 0

Views: 125

Answers (3)

James Brown
James Brown

Reputation: 37424

$ awk '/vm/ {printf "%s%s", $0, (++i%3?OFS:ORS)}' log.txt
[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0

Walk-thru:

/vm/ {                                 # if vm on the record
    printf "%s%s", $0, (++i%3?OFS:ORS) # print record and OFS
}                                      # every 3rd time print ORS

Since there in fact was more that 3 rows in a group, use this:

$ awk '/vm/ {buf=buf OFS $0; next} buf!="" {print buf; buf=""}'

It buffers records and prints them out after it encounters a record that doesn't match /vm/. It may case a problem if you have consecutive groups in your file. You may end-up with longer-than expected lines.

$ cat > process.awk
/vm/ {              # if vm string in the record
    buf=buf OFS $0  # append the record $0 to the buffer variable buf
    next            # skip the rest of script for this record, ie.
}                   # only records without vm match get past this point
buf!="" {           # if the buffer is not empty
    print buf       # print it out
    buf=""          # empty the buffer
}
$ awk -f process.awk log.txt

Upvotes: 0

Jean-François Fabre
Jean-François Fabre

Reputation: 140256

Another answer using sed only

/vm/{
H
x
s/\n/ /g
s/ \[kfg-ap.\] out: / /
x
blab
}
x
p
:lab

invoke like this (save above file as filter.sed):

sed -n -f filter.sed text.txt 

If vm is matched, then stores in the hold buffer. Then swaps the whole buffer to remove newlines and useless kfg prefixes in the line, swap again.

If not matched, swap the buffer again and print.

Rather simple & works great (cornercase: if log ends with the vm lines they may be omitted)

Upvotes: 0

Jean-François Fabre
Jean-François Fabre

Reputation: 140256

You were almost there: Just accumulate in a variable and print in the end:

awk 'BEGIN{s="";} /vm/ {s = s $0 " "} END {print s}' log.txt

You can also use your exact construction and convert the newlines:

awk '/vm/ {printf $0 " ";getline; print $0}' log.txt | tr "\n" " "

Upvotes: 1

Related Questions