Reputation: 1545
I have an output from a command that looks like the following:
hw.sensors.cpu0.temp0=39.00 degC
hw.sensors.acpitz0.temp0=27.80 degC (zone temperature)
The desired awk
output is as follows:
# TYPE hw_sensors gauge
hw_sensors{sensor="cpu0" reading="temp0"} 39
hw_sensors{sensor="acpitz0" reading="temp0"} 27
My thinking at the moment is a bit messy (I'm no awk
guru !), so my effort so far looks like this:
sysctl hw.sensors | fgrep temp0 | sed 's/\./_/g' | awk '{FS="="; print "# TYPE "$1" gauge\n"$1" "$2}' | sed -E 's/_[[:digit:]]{1,2}.*$//g'
I guess I could continue with more pipes, but that is most likely the wrong method !
Upvotes: 1
Views: 3982
Reputation: 204311
Assuming that testing for temp0 really is necessary and that your input can contain multiple types of report:
sysctl hw.sensors |
awk -F'[.=]' '
!/temp0/ { next }
{ type = $1 "_" $2 }
!doneHdr[type]++ { printf "# TYPE %s gauge\n", type }
{ printf "%s{sensor=\"%s\" reading=\"%s\"} %d\n", type, $3, $4, $5 }
'
# TYPE hw_sensors gauge
hw_sensors{sensor="cpu0" reading="temp0"} 39
hw_sensors{sensor="acpitz0" reading="temp0"} 27
Upvotes: 2
Reputation: 16997
By using .
and =
as field separator using awk
, use column 3,4,5
sysctl hw.sensors | awk -F'[.=]' -v fmt='hw_sensors{sensor="%s" reading="%s"} %d\n' '/temp0/{ printf(fmt,$3,$4,$5) }'
Better Readable version
sysctl hw.sensors | \
awk -F'[.=]' -v fmt='hw_sensors{sensor="%s" reading="%s"} %d\n' '
/temp0/{
printf(fmt,$3,$4,$5)
}'
Explanation
-F'[.=]'
set field separatorhw.sensors.cpu0.temp0=39.00 degC
^ ^ ^ ^ ^ ^
col1 col2 col3 col4 col5 col6
-v fmt='hw_sensors{sensor="%s" reading="%s"} %d\n'
variable fmt
contains format string, similar to c/c++
,/temp0/{
search for line/row/records contains temp0
printf(fmt,$3,$4,$5)
print your fields finallyUpvotes: 3
Reputation: 26531
This might be the easiest for you and most adaptable:
awk 'BEGIN{FS="="}'
{key=$1; value=$2}
{split(key,k,/[.]/)}
{split(value,v)}
{print k[1]"_"k[2]"{sensor=\042" k[3] "\042 reading=\042"k[4]"\042}",v[1]}'
This works in the following way:
split each line in a key and value pair:
line: hw.sensors.cpu0.temp0=39.00 degC
=> key=hw.sensors.cpu0.temp0
=> value=39.00 degC
split the key in subparts based on the dot as delitimer, store the parts in array k
:
key=hw.sensors.cpu0.temp0
split(key,k,/[.]/)
=> k=(hw,sensor,cpu0,temp0)
split the value in subparts based on a blank as delimiter, sotre the parts in array v:
value=39.00 degC
split(value,v)
=> k=(39.00,degC)
Reassemble the parts the way you like:
print k[1]"_"k[2]"{sensor=\042" k[3] "\042 reading=\042"k[4]"\042}",v[1]
This method is very flexible, as you can now put conditions on the parts to determine the reassembling rule: example:
(k[2]=="sensor"){ print k[1]"_"k[2]"{sensor=\042" k[3] "\042 reading=\042"k[4]"\042}",v[1] }
(k[2]=="dog") { print "This dog is",v[1], "cm long" }
Upvotes: 3
Reputation: 133710
Could you please try following.
awk -F'[.=]' -v s1="\"" '{print $1"_"$2"{"$2"="s1 $3 s1 " reading="s1 $4 s1 "} " $5+0}' Input_file
Upvotes: 2