Reputation:
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:
======================================================================
[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
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
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
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