Basic bash script awk and a division

2019-07-31 19:16发布

问题:

First sorry for this basic question. But i´m not a programmer and need some help.

I have a command that give me the temperature of a sensor.

Example:

root@machine:~ $ snmpwalk 172.69.4.25 -v 2c -c rocommunity .1.3.6.1.3.1.1.4
iso.3.6.1.3.1.1.4.1.2.5.116.101.109.112.49.1 = STRING: "31625"

And a small basic bashscript that give me only the value of the string.

#!/bin/bash
SLAVE="/sys/devices/w1_bus_master1/28-80000007e290/w1_slave"
OUTPUT=$(/bin/cat $SLAVE | /usr/bin/awk -F 't=' ' { printf $2 } ')
echo $OUTPUT

w1_slave file is as below

25 01 55 00 7f ff 0c 0c 08 : crc=08 YES
25 01 55 00 7f ff 0c 0c 08 t=31625

But it´s a temperature, and i need the value with a / 1000 division. 31625 realy are 31.625 degress.

If i put

#!/bin/bash
SLAVE="/sys/devices/w1_bus_master1/28-80000007e290/w1_slave"
OUTPUT=$(/bin/cat $SLAVE | /usr/bin/awk -F 't=' ' { printf $2 / 1000 } ')
echo $OUTPUT

Give me

root@machine:~ $ /opt/scripts/gettemp.sh
031.625

031.625 is the result, but i don´t know why no put only 31.625 and remove the first 0,

Are i doing something wrong? Could anybody Help me?

Thanks Best Regards

回答1:

If the problem is the awk formatting, try this:

#!/bin/bash
SLAVE="/sys/devices/w1_bus_master1/28-80000007e290/w1_slave"
OUTPUT=$(/bin/cat $SLAVE | grep -o "t=.*" |  /usr/bin/awk -F 't=' ' { printf "%.3f",$2 / 1000 } ')
echo $OUTPUT

Anyway, as @Ed Morton said, by default awk does not pad with zero by default. It would be needed a sample output of the /sys/devices/w1_bus_master1/28-80000007e290/w1_slave file to clarify the question.



回答2:

The problem is you're printing the $2 value divided by 1000 from both lines and using printf to do so with no terminating \n.

So from your first input line where there is no t= separator the value of $2 is the NULL string which when you divide by 1000 results in the numeric output 0 but not followed by a newline since you incorrectly use printf.

From your 2nd line you get the output 31.625 but it's tacked onto the end f the same line that the 0 was produced on.

a) Never do printf $2 (or any other field that contains input data), always printf "%s", $2 instead - imagine the difference when $2 contains printf formatting characters like %s.

b) Unless you have some need for formatting, use print instead of printf.

c) If you want newlines with printf then include them in the format string

d) If you only want output from input lines that match some pattern, then write code to perform that test.

This is probably what you really want:

awk -F 't=' 'NF>1{print $2 / 1000}'

I still have no clue what the initial snmpwalk code snippet is there for in the question though and wrt the rest of your shell script - don't use all upper case for non-exported variable names and do avoid UUOC and do quote your variables:

#!/bin/bash
slave="/sys/devices/w1_bus_master1/28-80000007e290/w1_slave"
output=$(awk -F 't=' 'NF>1{print $2 / 1000}' "$slave")
echo "$output"