Bash: How to do decimal number division? [duplicate] - bash

This question already has answers here:
Division in script and floating-point
(6 answers)
Closed 9 years ago.
$num=12.53
How can I divide by 5 and get a decimal result in bash script?
$(($num/5)) doesn't work.

BASH doesn't support decimal point arithmetic. You need to use bc or awk:
num=12.53
bc -l <<< "scale=2; $num/5"
2.50
OR using awk:
awk -v n=$num 'BEGIN {printf "%.2f\n", (n/5)}'

kent$ num=12.53
kent$ echo "scale=2;$num/5"|bc
2.50
kent$ awk -v n="$num" 'BEGIN{printf "%.2f\n", n/5}'
2.51
note the bc's scale and printf's format may give different result.

Related

substraction of variable having float value is not working [duplicate]

This question already has answers here:
Floating-point arithmetic in UNIX shell script
(4 answers)
Closed 3 years ago.
I am executing below as part of bash script on solaris 10.
MEM_USED_PC=`prstat -Z 1 1 | grep -i sz | awk '{print $5}' | sed 's/%//'`
MEM_TOTAL_PC=100
MEM_FREE_PC=$(($MEM_TOTAL_PC-$MEM_USED_PC))
but echo $MEM_FREE_PC gives below error:
100-6.5: syntax error: invalid arithmetic operator (error token is ".5")
What could be the problem?
You can use the calculator CLI, bc
MEM_FREE_PC=$(echo "$MEM_TOTAL_PC - $MEM_USED_PC" | bc)
echo $MEM_FREE_PC
Since bash doesn't support floating point, you need something like awk to compute the result:
$ MEM_TOTAL_PC=100
$ MEM_USED_PC=99.33
$ MEM_FREE_PC=$(awk -v MEM_TOTAL_PC=$MEM_TOTAL_PC -v MEM_USED_PC=$MEM_USED_PC 'BEGIN {print MEM_TOTAL_PC-MEM_USED_PC}')
$ echo $MEM_FREE_PC
0.67

Unable to pass shell variables into awk [duplicate]

This question already has answers here:
How to use awk variables in regular expressions?
(5 answers)
Closed 6 years ago.
I am trying to get data between sequences of numbers, for instance:
100000000
1 2 3 4
5 6 7 8
....
100001000
....
200000000
I match the patterns using awk and I can use it successfully without using variables, for instance:
awk '/10000000 /{flag=1;next}/10001000/{exit}flag' input.dat
However when I try to use shell variables within this command, it gives no output whatsoever:
for i in {1..4}
do
step1=$(($i*10000000))
step2=$(($step1+1000))
awk -v arg1="$step1" -v arg2="$step2" '/arg1 /{flag=1;next}/arg2 /{exit}flag' input.dat
done
Is there something obvious I'm missing?
Regex literal /.../ doesn't allow variables. You can use ~ operator for regex matching in regex with variables:
awk -v arg1="$step1" -v arg2="$step2" '$0 ~ arg1 " "{flag=1; next}
$0 ~ arg2{exit} flag' input.dat

Grep the first number in a line [duplicate]

This question already has answers here:
Printing only the first field in a string
(3 answers)
Closed 6 years ago.
I have a file that has lines of numbers and a file:
2 20 3 file1.txt
93 21 42 file2.txt
52 10 12 file3.txt
How do I use grep, awk, or some other command to just give me the first numbers of each line so that it will only display:
2
93
52
Thanks.
So many ways to do this. Here are some (assuming the input file is gash.txt):
awk '{print $1}' gash.txt
or using pure bash:
while read num rest
do
echo $num
done < gash.txt
or using "classic" sed:
sed 's/[ \t]*\([0-9]\{1,\}\).*/\1/' gash.txt
or using ERE with sed:
sed -E 's/[ \t]*([0-9]+).*/\1/' gash.txt
Using cut is problematic because we don't know if the whitespace is spaces or tabs.
By the way, if you want to add the total number of lines:
awk '{total+=$1} END{print "Total:",total}' gash.txt
You can use this:
grep -oE '^\s*[0-9]+' filename
To handle the leading spaces, I'm currently out of options. You better accept the awk answer.
You can use awk
awk '{print $1}' file

Extract Information From File Name in Bash [duplicate]

This question already has answers here:
How to split a string into an array in Bash?
(24 answers)
Closed 7 years ago.
Suppose I have a file with a name ABC_DE_FGHI_10_JK_LMN.csv. I want to extract the ID from the file-name i.e. 10 with the help of ID position and file-name separator. I have following two inputs
File-name_ID_Position=4; [since 10 is at fourth position in file-name]
File-name_Delimiter="_";
Here ID can be numeric or alpha-numeric. So how extract the 10 from above file with the help of above two inputs. How to achieve this in bash?
Instead of writing a regex in bash, I would do it with awk:
echo 'ABC_DE_FGHI_10_JK_LMN.csv' | awk -F_ -v pos=4 '{print $pos}'
or if you want the dot to also be a delimiter (requires GNU awk):
echo 'ABC_DE_FGHI_10_JK_LMN.csv' | awk -F'[_.]' -v pos=4 '{print $pos}'

How to write a bash and define awk constants in command line [duplicate]

This question already has answers here:
Using awk with variables
(3 answers)
Closed 8 years ago.
As a part of my bash, I want to pass some constant from command line to awk. For example, I want to subtract constant1 from column 1 and constant2 from column 5
$ sh bash.sh infile 0.54 0.32
#!/bin/bash
#infile = $1
#constant1 = $2
#constant2 = $3
cat $1 | awk '{print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6}'
thank you very much for your help
As awk is it's own language, by default it does not share the same variables as Bash. To use Bash variables in an awk command, you should pass the variables to awk using the -v option.
#!/bin/bash
awk -v constant1=$2 -v constant2=$3 '{print($1-constant1),($5-constant2)}' $1
You'll notice I removed cat as there is no need to pipe cat into awk since awk can read from files.
you need to remove gaps when defining vaariables:
#!/bin/bash
infile=$1
constant1=$2
constant2=$3
cat $1 | awk '{print $1 $2 $3 $4 $5 $6}'

Resources