2011-08-28 4 views
0

Я пытаюсь проверить, если значение я читать из текстового файла равен нулю:Проблема с плавающей точкой сравнения

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

С первым условием не является проблемой, поскольку f5 являются целыми числами. Проблема возникает из второго условия. Я получаю сообщение об ошибке:

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

Я попытался несколько предложений, которые я нашел в различных форумах, таких как использование echo $line | cut -d" " -f7 | bc -l и без двойных кавычек, и т.д. Тем не менее, ошибка сохраняется. f7 - положительное число и задается с 3 знаками после запятой. Удаление десятичных знаков или аппроксимация не является вариантом, потому что мне нужен результат, равный нулю (0.000).

ответ

1

Вместо этого используйте сравнение строк. Заменить:

-eq 0 

с:

= '0.000' 

TZ:

раздел Script от комментариев:

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 

Моя интерпретация псевдо-Python:

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 

Это то, что вы намеревались?

+0

Done, спасибо! – mirix

+0

Не работает. Ошибки исчезли. Однако с ошибками программа работала нормально и создавала правильный выход. Теперь это не так. – mirix

+0

Опубликовать сценарий? Или часть, которая идет не так? Возможно, это не связано с этим, поэтому вы можете отправить новый вопрос. –

2

Как правило, вы не можете сравнивать числа с плавающей запятой для равенства. Это связано с тем, что двоичное представление десятичных чисел неточно и вы получаете ошибки округления. Это стандартный ответ, который даст вам большинство других.

В этом конкретном случае вам фактически не нужно сравнивать числа с плавающей запятой, потому что вы просто проверяете, отображает ли какой-либо текст определенный номер. Поскольку вы находитесь в оболочке, вы можете использовать регулярное сравнение строк с «0.000» - если ваши данные округлены таким образом - или с помощью регулярных выражений с grep/egrep. Что-то вроде

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

будет соответствовать 0, 0,0, 0,00, и т.д., и будет выходить с указанием успеха или неудачи, которые вы можете использовать в окружении, если заявление:

if cut and pipe soup | egrep ... ; then 
    ... 
fi 
Смежные вопросы