0

I am a beginner in shell scripting. I Have a decimal value and I want to compare it in a if statement. I was trying like this

size1=`${PATH_TO_CLIENT}sqlplus $IMPUSER/$IMPPWD@$ENDPOINT<< EOF | sed -n '/^\s*SIZE_GB$/{n;n;n;p}'
select owner, sum(bytes)/1024/1024/1024 Size_GB from dba_segments where owner = 'XXXXXX' group by owner;
exit;
EOF`
echo "Total data is = ${size1}"

if (($size1 > 7.50 | bc))
then
  echo '### THE DATA SIZE IS GREATER THAN 7.5 GB ###'
  echo 'Total data is ${size1}'
  exit 1
else
  echo 'Total data is {$size1}'
  echo '### THE DATA SIZE IS OKAY ###'
fi

The output I am getting is

Total data is = 11.2345
./testDelete.sh: line 65: ((: 11.2345 > 7.50 | bc: syntax error: invalid arithmetic operator (error token is ".2345 > 7.50 | bc")
Total data is {$size1}
### THE DATA SIZE IS OKAY ###

So size1 variable is able to store the value but I was not able to compare it. Please can anyone help me with it.

  • Start with http://mywiki.wooledge.org/BashFAQ/022 – Shawn May 15 '21 at 07:13
  • And with https://shellcheck.net to help with your other issues. – Shawn May 15 '21 at 07:16
  • @narutouzumaki : POSIX shell suports `$((....))`, but AFIK it does not suport `(( .... ))`, and since you intend to use `bc` for the calculation, I don't see the point in using arithmetic context. Do you **have** to use `sh`? In zsh, you would have floating point arithmetic on the shell level. – user1934428 May 17 '21 at 11:19

4 Answers4

2

you could change: if (($size1 > 7.50 | bc)) to:

if (( $(echo "$size1 > 7.50" | bc) ))

The $(...) makes the command echo "$size1 > 7.50" | bc being executed. This produces 0 or 1.

Luuk
  • 12,245
  • 5
  • 22
  • 33
  • I tried if (($(echo "$size1 > 7.5" | bc) )) then echo '### first condition THE DATA SIZE IS GREATER THAN 11.5 GB ###' but the output was ```bc: command not found``` – naruto uzumaki May 15 '21 at 07:44
  • Then you might need to install `bc` (see: [Installing BC and any maths extension](https://askubuntu.com/questions/550985/installing-bc-and-any-maths-extension)) – Luuk May 15 '21 at 07:59
  • @narutouzumaki what OS are you on that doesn't have `bc`? – glenn jackman May 15 '21 at 20:09
2

I like to do small unsafe awk wrapper:

float_cmp() {
    awk "BEGIN{exit(!( $* ))}" <&-
}

if float_cmp "$size1 > 7.50"; then
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
1

A while ago, I had the same problem. I did some searches and ended up with this function:

function compare_floats(){
    ## https://stackoverflow.com/questions/8654051/how-to-compare-two-floating-point-numbers-in-bash
    ## usage: is_smaller="$(compare_floats "$num1" "<" "$num2")"  ## returns true or false

    local float1="$1"
    local oper="$2"
    local float2="$3"

    ## compare
    case "$oper" in
         "<" ) [ $(awk '{printf($1 <  $2) ? 1 : 0}' <<< "$float1 $float2") -eq 1 ] && local result="true" || local result="false" ;;
         "=" ) [ $(awk '{printf($1 == $2) ? 1 : 0}' <<< "$float1 $float2") -eq 1 ] && local result="true" || local result="false" ;;
         ">" ) [ $(awk '{printf($1 >  $2) ? 1 : 0}' <<< "$float1 $float2") -eq 1 ] && local result="true" || local result="false" ;;
    esac

    echo "$result" ;}


condition="$(compare_floats 41.4 "<" 19.2)"
[ "$condition" == "true" ] && <do_this> || <do_that>
nino
  • 554
  • 2
  • 7
  • 20
1

Pure shell solution

$ if [ 7 \> 7.5 ]; then echo 'Y'; else echo 'N'; fi
N
$ if [ 7.4 \> 7.5 ]; then echo 'Y'; else echo 'N'; fi
N
$ if [ 7.5 \> 7 ]; then echo 'Y'; else echo 'N'; fi
Y
$ if [ 7.5 \> 7.4 ]; then echo 'Y'; else echo 'N'; fi
Y
$ if [ 7 \< 7.5 ]; then echo 'Y'; else echo 'N'; fi
Y
$ if [ 7.4 \< 7.5 ]; then echo 'Y'; else echo 'N'; fi
Y
$ if [ 7.5 \< 7 ]; then echo 'Y'; else echo 'N'; fi
N
$ if [ 7.5 \< 7.4 ]; then echo 'Y'; else echo 'N'; fi
N
$ if [ 7 = 7.5 ]; then echo 'Y'; else echo 'N'; fi
N
$ if [ 7.4 = 7.5 ]; then echo 'Y'; else echo 'N'; fi
N
$ if [ 7.5 = 7.5 ]; then echo 'Y'; else echo 'N'; fi
Y
Darkman
  • 2,941
  • 2
  • 9
  • 14