0

I am trying to check if a value I read from a text file is zero:

[[ $(echo $line | cut -d" " -f5) -gt 0 ]] && [[ $(echo $line | cut -d" " -f7 | bc -l) -eq 0 ]]

With the first condition there is no problem because f5 are integers. The problem comes form the second condition. I receive this error message:

[[: 1.235: syntax error: invalid arithmetic operator (error token is ".235")

I have tried several suggestions I found in different forums such as using echo $line | cut -d" " -f7 | bc -l with and without double quotes, etc. However, the error persist. f7 is a positive number and is given with 3 decimal places. Removing decimals or approximating is not an option because I need the result to be exactly zero (0.000).

2 Answers 2

2

Generally, you can't compare floating-point numbers for equality. This is because the binary representation of decimal numbers is not precise and you get rounding errors. This is the standard answer that most others will give you.

In this specific case, you don't actually need to compare floating-point numbers, because you're just testing whether some text represents a specific number. Since you're in shell, you can either use a regular string compare against "0.000" - assuming your data is rounded in that way - or using regular expressions with grep/egrep. Something like

egrep -q '0(|\.0+)'

Will match 0, 0.0, 0.00, etc, and will exit indicating success or failure, which you can use in the surrounding if statement:

if cut and pipe soup | egrep ... ; then
  ...
fi
Sign up to request clarification or add additional context in comments.

Comments

1

Use a string comparison instead. Replace:

-eq 0

with:

= '0.000'

TZ:

Script section from comment:

for clus in $(ls *.cluster) ; do
    while read line ; do
        if [[ $(echo $line | cut -d" " -f11) -gt 0 ]] && [[ "$(echo $line | cut -d" " -f15 | bc -l)" = '0.000' ]] ; then
            cat $(echo $line | cut -d" " -f6).pdb >> test/$(echo $line | cut -d" " -f2)_pisa.pdb
        fi
    done < $clus
done

My pseudo-Python interpretation:

for clus in *.cluster:
    for line in clus:
        fields = line.split(' ')
        # field numbers are counting from 1 as in cut
        if int(field 11) > 0 and str(field 15) == '0.000':
            fin_name = (field 6) + '.pdb'
            fout_name = (field 2) + '_pisa.pdb'
            cat fin_name >> fout_name

Is that what you intended?

4 Comments

It does not work. The errors are gone. However, with the errors the program was working fine and producing the right output. Now it does not.
Post the script? Or the part that's going wrong? Might be unrelated to this, so you might want to post a new question.
for clus in $(ls *.cluster) ; do while read line ; do if [[ $(echo $line | cut -d" " -f11) -gt 0 ]] && [[ "$(echo $line | cut -d" " -f15 | bc -l)" = '0.000' ]] ; then cat $(echo $line | cut -d" " -f6).pdb >> test/$(echo $line | cut -d" " -f2)_pisa.pdb fi done < $clus done
It works now. There were several problems ;-) [[ "$(echo "$line" | cut -c32-35)" != ' 0' ]] && [[ "$(echo "$line" | cut -c43-47)" == '0.000' ]] cat "$(echo "$line" | cut -c11-21)".pdb >> ./test/"$(echo "$line" | cut -c1-6)"_pisa.pdb

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.