Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtracting strings (that are numbers) in a shell script

Tags:

bash

shell

math

I made a shell script that finds the size of a directory, returning it in human readable format (e.g., 802M or 702K). I want to calculate the difference between the sizes.

Here's my shell script so far:

#!/bin/bash

current_remote_dir_size=789M
new_remote_dir_size=802M
new_size=`echo ${new_remote_dir_size} | grep -o [0-9]*`
current_size=`echo ${current_remote_dir_size} | grep -o [0-9]*`

echo "${new_size}-${current_size}"

But the output of the script is just

-

How can I make the subtraction work?

like image 670
hao_maike Avatar asked Jan 16 '12 01:01

hao_maike


People also ask

What is $? == 0 in shell script?

$? is the exit status of the most recently-executed command; by convention, 0 means success and anything else indicates failure. That line is testing whether the grep command succeeded. The grep manpage states: The exit status is 0 if selected lines are found, and 1 if not found.

What does ${} mean in shell?

$() – the command substitution. ${} – the parameter substitution/variable expansion.

What is $# in shell script?

$# : This variable contains the number of arguments supplied to the script. $? : The exit status of the last command executed. Most commands return 0 if they were successful and 1 if they were unsuccessful. Comments in shell scripting start with # symbol.

What is $1 and $2 in shell script?

These are positional arguments of the script. Executing ./script.sh Hello World. Will make $0 = ./script.sh $1 = Hello $2 = World. Note. If you execute ./script.sh , $0 will give output ./script.sh but if you execute it with bash script.sh it will give output script.sh .


3 Answers

You can do basic integer math in bash by wrapping the expression in $(( and )).

$ echo $(( 5 + 8 ))
13

In your specific case, the following works for me:

$ echo "${new_size}-${current_size}"
802-789
$ echo $(( ${new_size}-${current_size} ))
13

Your output at the end is a bit odd. Check that the grep expression actually produces the desired output. If not, you might need to wrap the regular expression in quotation marks.

like image 76
Daniel Beck Avatar answered Sep 19 '22 05:09

Daniel Beck


You don't need to call out to grep to strip letters from your strings:

current_remote_dir_size=789M
current_size=${current_remote_dir_size%[A-Z]}
echo $current_size  # ==> 789

new_remote_dir_size=802M
new_size=${new_remote_dir_size%[A-Z]}
echo $new_size      # ==> 802

See Shell Parameter Expansion in the bash manual.

like image 24
glenn jackman Avatar answered Sep 22 '22 05:09

glenn jackman


All you need is:

echo $((${new_remote_dir_size/M/}-${current_remote_dir_size/M/}))
  • $((a+b - 4)) can be used for arithmetic expressions
  • ${string/M/} replaces M in string with nothing. See man bash, Section String substitution, for more possibilities and details.
like image 23
user unknown Avatar answered Sep 22 '22 05:09

user unknown