【问题标题】:Compare non integers with if将非整数与 if 进行比较
【发布时间】:2017-06-21 10:55:10
【问题描述】:

我想查看一个包含一列十进制数字的文件,并找到所有(+ 或 -)2.2 of 100 的条目并将它们重定向到一个文件。这是我目前得到的。

cat numfile.txt

100.56
99.6
96.8
86.77
105.7
95.5
92.4
101.1
102.5
98.7

这是我一直在尝试的

while read line
  do
    num=2.2

    if [ $line -ge $num ] 
      then 
        echo $line > savefile.txt
    fi
  done < numfile.txt

期望的输出

cat savefile.txt

100.56
99.6
101.1
98.7

【问题讨论】:

  • 为什么选择 Mike Wodarczyk 的答案?我回答了第一个,我提出了两种不同的方法。马克回答错了,在我发表评论后采取我自己的方法。

标签: bash if-statement conditional


【解决方案1】:

我建议通过“bc”发送比较计算。

例如

  result=$(echo "scale=2;  ( $line >= 100 - $num )  &&  ($line <= 100 + $num  ) " | bc)

$result 如果为假,则为“0”,如果为真,则为“1”。 您的 if 语句如下所示:

 if [ $(echo "scale=2;  ( $line >= 100 - $num )  &&  ($line <= 100 + $num  ) " | bc) -eq 1 ] ; 
     then 
         ... # do true stuff
  fi

【讨论】:

  • 问题不是 $line > $num。 $line 是 100+/-$num
  • @Mike Wodarczyk 非常感谢您的帮助!!!如果你不介意我还有最后一个问题。如何在同一个脚本中执行多个(同时读取行)而不使变量行与其他行发生冲突?
  • 您可以使用除 line 之外的其他变量名。一边读艾琳;做...同时阅读bline; do ... 变量将是 aline 和 bline。我不建议使用 aline 和 bline 这两个名称,但要适合这种情况。
【解决方案2】:

可能不是更好,但有效:

 if [ `echo "scale=2;sqrt((100-$line)^2)<=$num" | bc` -eq 1 ]

另一种方式:

num=2.2
awk '{if (sqrt((100-$1)^2) < '$num') { print $1}}' < numfile.txt > savefile.txt

【讨论】:

  • 乍一看,这段代码似乎自相矛盾。
  • 1. bash 仅支持整数。 2. bc 和 awk 都没有 abs 功能。
  • 你可以像这样在 bc 中创建一个 abs 函数: printf "scale=2;\ndefine myabs ( x ) { \n if ( x > 0 ) return x; \n return -1 * x ; \n };\n myabs (-11.3 ) \n" |公元前
【解决方案3】:

将这两种方法稍微混合一下:

c=2.2

while read n; do
    (( $(bc -l <<< "sqrt(($n-100)^2) <= $c") )) && echo $n
done < numfile.txt > savefile.txt

(( )) 条件如果其内容不等于 0,则计算为真,如果条件计算为真,bc 打印1。

-l 选项定义数学库,它启用sqrt 函数,并将scale 设置为20。

我已将重定向移到循环之外,以避免每次都打开和关闭文件描述符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 2021-09-16
    相关资源
    最近更新 更多