I don't want array to do word splitting - bash

Below is my code. But bash is doing word splitting therefore I have failure. How to make my script so that there is no word splitting.
namaSensor=$(sensors | egrep "°C" | awk '{print $0}' | awk -F ':' '{print $1}')
for sensor in $namaSensor
do
if [ $(sensors | grep -c "$sensor") -ne 0 ]
then
currentTemperature=$(sensors | egrep "$sensor" | awk '{print $0}' | awk -F '+' '{print $2}' | cut -c 1-4 | awk -F '.' '{print $1}')
maxTemperature=$(sensors | egrep "$sensor" | awk '{print $0}' | awk -F '+' '{print $3}' | cut -c 1-4 | awk -F '.' '{print $1}')
if [ $currentTemperature -lt $maxTemperature ]
then
printf "current temperature is %d°C and the maximum allowed temperature is %d°C\n" "$currentTemperature" "$maxTemperature"
printf "temperature is within the maximum allowed temperature\n"
echo "$sensor"
else
printf "current temperature is %d°C and the maximum allowed temperature is %d°C\n" "$currentTemperature" "$maxTemperature"
printf "temperature is more than the maximum allowed temperature\n"
#exit 255
fi
fi
done.
This is the output of sensors for my unit.
acpitz-virtual-0
Adapter: Virtual device
temp1: +40.0°C (crit = +111.0°C)
temp2: +40.0°C (crit = +111.0°C)
coretemp-isa-0000
Adapter: ISA adapter
Physical id 0: +34.0°C (high = +87.0°C, crit = +105.0°C)
Core 0: +31.0°C (high = +87.0°C, crit = +105.0°C)
Core 1: +22.0°C (high = +87.0°C, crit = +105.0°C)
Please help

As I understand you have your array splitted as following:
Physical
id
0
and so on. To change this behaviour you need to change your Internal Field Separator (IFS) to a newline. So your code should look like this:
IFS=$'\n'
nameSensor=$(sensors | egrep "°C" | awk '{print $0}' | awk -F ':' '{print $1}')
for sensor in $nameSensor
do
if [ $(sensors | grep -c "$sensor") -ne 0 ]; then
currentTemperature=$(sensors | egrep "$sensor" | awk '{print $0}' | awk -F '+' '{print $2}' | cut -c 1-4 | awk -F '.' '{print $1}')
maxTemperature=$(sensors | egrep "$sensor" | awk '{print $0}' | awk -F '+' '{print $3}' | cut -c 1-4 | awk -F '.' '{print $1}')
if [ $currentTemperature -lt $maxTemperature ]; then
printf "current temperature is %d°C and the maximum allowed temperature is %d°C\n" "$currentTemperature" "$maxTemperature"
printf "temperature is within the maximum allowed temperature\n"
echo "$sensor"
else
printf "current temperature is %d°C and the maximum allowed temperature is %d°C\n" "$currentTemperature" "$maxTemperature"
printf "temperature is more than the maximum allowed temperature\n"
#exit 255
fi
fi
done

Related

Concatenate results of commands in Bash

I was looking for a single one-liner to produce a line with all data:
These four [separate] commands produce the info I need, but I don't know how to concatenate them into a single line:
$ cat /proc/cpuinfo | grep "model name" | sed -n -e 's/^.*: //p'
ARMv6-compatible processor rev 7 (v6l)
$ lscpu | grep "CPU(s):" | awk '{print $2}'
1
$ lscpu | grep "CPU min MHz:" | awk '{print $4}'
700.0000
$ lscpu | grep "CPU max MHz:" | awk '{print $4}'
1000.0000
And I wanted to get:
ARMv6-compatible processor rev 7 (v6l) x1 #700 MHz (max #1000 MHz)
just using echo
echo $(cat /proc/cpuinfo | grep "model name" | sed -n -e 's/^.*: //p') \
x$(lscpu | grep "CPU(s):" | awk '{print $2}') \
#$(lscpu | grep "CPU min MHz:" | awk '{print $4}') \
'( max' $(lscpu | grep "CPU max MHz:" | awk '{print $4}') ')'
By the way, you could use just grep "model name" /proc/cpuinfo instead of cat /proc/cpuinfo | grep "model name"
One way.
paste -d ' ' <(awk '/^model name/{sub(/.+: /,"");print;exit}' /proc/cpuinfo) <(lscpu | awk '/CPU min MHz:/{printf " (max #%d MHz) ", $4} /CPU max MHz:/{printf "#%d MHz", $4} /^CPU\(s\):/{printf "x%s ", $2}')

echo output not getting assigned to a variable in shell script

end=echo $FSDB_FILE_NAME | rev | cut -d'_' -f 2 |rev
begin=echo $FSDB_FILE_NAME | rev | cut -d'_' -f 3 |rev
echo $end
echo $begin
echo abc_11204.00_15713.00_.csv | rev | cut -d'_' -f 2 |rev ---- This works
But echo $end is not printing anything
I even tried:
set end=echo abc_11204.00_15713.00_.csv | rev | cut -d'_' -f 2 |rev
echo $end
This prints empty
Please help me with this
Sample input : abc_123.00_345.00_xyz.csv
Output : end=345.00
begin=123.00
Could you please try following. Easy approach with awk.
start=$(echo "$input_variable" | awk -F'_' '{print $2}')
end=$(echo "$input_variable" | awk -F'_' '{print $3}')
When I print variable's values it will be as follows:
echo "$start"
123.00
echo "$end"
345.00

Bash awk: parsing variable string into another variable? [duplicate]

This question already has answers here:
Linux bash: Multiple variable assignment
(6 answers)
Closed 4 years ago.
I would like to extract all the values contained in $line and put them in variables var1, var2,... varn. I did use this previously to extract the vars from file (in.txt)
var1=$(awk '{print $1}' < in.txt)
var2=$(awk '{print $2}' < in.txt)
....
varn=$(awk '{print $n}' < in.txt)
How should I change my awk call so as to use $line instead of in.txt?
I tried these for example
echo $line | var2=$(awk '{print $2}')
or
var2=$(echo $line | awk '{print $2}')
but without success...
========== DETAIL==============
----- calling file:
.....
name=Matrix
line=$(sed -n '/^\[T\]/ {n;p}' in.txt)
echo 'line: ' $line
L1=$(./procline_matrix_vars.sh $line 30 $name)
echo 'L1: ' $L1
------- rocline_matrix_vars.sh:
#!/bin/bash
line=$1
choice=$2
var1=$(echo $line | awk '{print $1}')
var2=$(echo $line | awk '{print $2}')
var3=$(echo $line | awk '{print $3}')
var4=$(echo $line | awk '{print $4}')
if [ $choice == 30 ]; then
L1=$(printf '\n\n\n%s = [ %s %s %s %s \n' "$3" "$var1" "$var2" "$var3" "$var4")
fi
echo "${L1%.}"
a possible way:
line="aaa bbb ccc"
var=( $line )
echo "${var[1]}"
echo "my array has ${#var[#]} elements"
output
bbb
my array has 3 elements
maybe shortcut
var=( $( awk '{print $1, $2, $10}' file ) )

Bash- Converting a variable to human readable format (KB, MB, GB)

In my bash script, I run through a list of directories and read in the size of each directory to a variable using the du command. I also keep a running total of the total size of the directories. The only problem is that after I get the total size, it's in an unreadable format (ex. 64827120). How can I convert the variable containing this number into GBs, MBs, etc?
You want to use du -h which gives you a 'human readable' output ie KB, MB, GB, etc.
You can use numfmt to convert raw (decimal) numbers
to human-readable form. 
Use --to=iec to output binary-prefix numbers
(i.e., K=1024, M=220, etc.)
$ printf '%s %s\n' 1000000 foo 1048576 bar | numfmt --to=iec
977K foo
1.0M bar
and use --to=si to output metric-prefix numbers
(i.e., K=1000, M=106, etc.)
$ printf '%s %s\n' 1000000 foo 1048576 bar | numfmt --to=si
1.0M foo
1.1M bar
If you specifically want to get “MB”, “GB”, etc., use --suffix:
$ printf '%s %s\n' 1000000 foo 1048576 bar | numfmt --to=si --suffix=B
1.0MB foo
1.1MB bar
If your numbers are in a column other than the first
(as in Mik R’s answer), use --field:
$ printf '/home/%s %s\n' foo 1000000 bar 1048576 | numfmt --to=si --field=2
/home/foo 1.0M
/home/bar 1.1M
Or you can convert numbers on the command line (instead of using a pipe):
$ numfmt --to=si 1000000 1048576
1.0M
1.1M
Try using du -sh for getting summarise size in human readable, also you can find the command related help in manual.
Try below command, it will give you the size in Human readable format
du | tail -1 | awk {'print $1'} | awk '{ total = $1 / 1024 ; print total "MB" }'
du | tail -1 | awk {'print $1'} | awk '{ total = $1 / 1024/1024 ; print total "GB" }'
This is a combination of #Mahattam response and some others I combined which tallys the total amount in the standard format and then formats the output in human readable.
for path in $(awk -F: '{if ($3 >= 1000) print $6}' < /etc/passwd); do disk_usage=0; disk_usage=$(du -s ${path} | grep -oE '[[:digit:]]+'); echo "$path: $(echo $disk_usage | tail -1 | awk {'print $1'} | awk '{ total = $1 / 1024/1024 ; printf("%.2fGB\n", total) }')"; myAssociativeArray[${path}]=${disk_usage}; done ; total=$(IFS=+; echo "$((${myAssociativeArray[*]}))"); echo "Total disk usage: $(echo $total | tail -1 | awk {'print $1'} | awk '{ total = $1 / 1024/1024 ; printf("%.2fGB\n", total) }')"; unset total; unset disk_usage ;
How it works.
This could be anything you want to iterate through path list but in this example its just using the /etc/pass to loop over users paths source is here
for path in $(awk -F: '{if ($3 >= 1000) print $6}' < /etc/passwd)
It then calculates the usage per folder and extracts only digits from the output in the loop
disk_usage=0; disk_usage=$(du -s ${path} | grep -oE '[[:digit:]]+')
It outputs the nice formatting rounded to 2 decimal points
echo "$path: $(echo $disk_usage | tail -1 | awk {'print $1'} | awk '{ total = $1 / 1024/1024 ; printf("%.2fGB\n", total) }')";
Adds this to the bash associative array
myAssociativeArray[${path}]=${disk_usage}
then it sums the total value in the original amount from the array
total=$(IFS=+; echo "$((${myAssociativeArray[*]}))")
then we use the same fancy output formatting to show this nicely
echo "Total disk usage: $(echo $total | tail -1 | awk {'print $1'} | awk '{ total = $1 / 1024/1024 ; printf("%.2fGB\n", total) }')";
I used a variation of this for calculating cPanel Resellers accounts disk usage in the below monster oneliner.
Reseller="CPUsernameInputField"; declare -A myAssociativeArray ; echo "==========================================" | tee -a ${Reseller}_disk_breakdown.txt ; echo "Reseller ${Reseller}'s Disk usage by account"| tee -a ${Reseller}_disk_breakdown.txt; for acct in $(sudo grep ${Reseller} /etc/trueuserowners | cut -d: -f1); do disk_usage=0; disk_usage=$(du -s /home/${acct} | grep -oE '[[:digit:]]+'); echo "$acct: $(echo $disk_usage | tail -1 | awk {'print $1'} | awk '{ total = $1 / 1024/1024 ; printf("%.2fGB\n", total) }')" | tee -a ${Reseller}_disk_breakdown.txt ; myAssociativeArray[${acct}]=${disk_usage}; done ; total=$(IFS=+; echo "$((${myAssociativeArray[*]}))"); echo "Total disk usage: $(echo $total | tail -1 | awk {'print $1'} | awk '{ total = $1 / 1024/1024 ; printf("%.2fGB\n", total) }')" | tee -a ${Reseller}_disk_breakdown.txt; unset total; unset disk_usage;echo "==========================================" | tee -a ${Reseller}_disk_breakdown.txt ; echo "Sorted by top users" | tee -a ${Reseller}_disk_breakdown.txt; for key in "${!myAssociativeArray[#]}"; do printf '%s:%s\n' "$key" "${myAssociativeArray[$key]}"; done | sort -t : -k 2rn | tee -a ${Reseller}_disk_breakdown.txt;echo "==========================================" | tee -a ${Reseller}_disk_breakdown.txt ;for key in "${!myAssociativeArray[#]}"; do USER_HOME=$(eval echo ~${key}); echo "Disk breakdown for $key" | tee -a ${Reseller}_disk_breakdown.txt ; sudo du -h ${USER_HOME} --exclude=/app --exclude=/home/virtfs| grep ^[0-9.]*[G,M] | sort -rh|head -n20 | tee -a ${Reseller}_disk_breakdown.txt;echo "=======================================" | tee -a ${Reseller}_disk_breakdown.txt; done

Shell Scripting command not found Error

I'm new to programming with shell and want to ask what is wrong with my code?
#!/bin/bash
#DHT11
SCRIPT="/var/www/ErnestynoFailai/scripts/DHT 11 4"
#DHT22
#SCRIPT="/root/to/folder/DHT 22 4"
#AM2302
#SCRIPT="/root/to/folder/DHT 2302 4"
HUMIDITY=`$SCRIPT | grep "Temp" | awk -F " " '{print $7}'`
TEMPRATURE=`$SCRIPT | grep "Temp" | awk -F " " '{print $3}'`
#-a = AND = &&
while [ $HUMIDITY=="" -a $TEMPRATURE=="" ]
do
$HUMIDITY=`$SCRIPT | grep "Temp" | awk -F " " '{print $7}'`
$TEMPRATURE=`$SCRIPT | grep "Temp" | awk -F " " '{print $3}'`
done
echo "$HUMIDITY"
echo "$TEMPRATURE"
I'm getting:
line 14 or 15 =26: or =: command not found...
There are two problems:
These lines are not returning anything, or at least a string:
HUMIDITY=`$SCRIPT | grep "Temp" | awk -F " " '{print $7}'`
TEMPRATURE=`$SCRIPT | grep "Temp" | awk -F " " '{print $3}'`
This is causing =: command not found errors.
Your while condition needs to be
while [[ $HUMIDITY == "" && $TEMPRATURE == "" ]]
Finally, while not causing problems, TEMPERATURE is misspelled, which might cause you grief later on.
Variables have to be assigned without leading $:
HUMIDITY=`$SCRIPT | grep "Temp" | awk -F " " '{print $7}'`
TEMPRATURE=`$SCRIPT | grep "Temp" | awk -F " " '{print $3}'`

Resources