unix 数的绝对值

6mw9ycah  于 2023-08-04  发布在  Unix
关注(0)|答案(9)|浏览(160)

我想在bash中通过下面的代码获取一个数字的绝对值:

#!/bin/bash
echo "Enter the first file name: "
read first

echo "Enter the second file name: "
read second

s1=$(stat --format=%s "$first")
s2=$(stat -c '%s' "$second")

res= expr $s2 - $s1

if [ "$res" -lt 0 ]
then
        res=$res \* -1
fi

echo $res

字符串
现在我面临的问题是在if语句中,无论我改变什么,它总是在if中,我试图把[[ ]]放在语句周围,但什么也没有。
以下是错误:

./p6.sh: line 13: [: : integer expression expected

z0qdvdin

z0qdvdin1#

你可以只取${var#-}
${var#Pattern}$var中删除与$var前端匹配的$Pattern的最短部分。tdlp
示例如下:

s2=5; s1=4
s3=$((s1-s2))

echo $s3
-1

echo ${s3#-}
1

字符串

b0zn9rqh

b0zn9rqh2#

$ s2=5 s1=4
$ echo $s2 $s1
5 4
$ res= expr $s2 - $s1
1
$ echo $res

字符串
第四行实际发生的是res被设置为nothing并导出为expr命令。因此,当您运行[ "$res" -lt 0 ]时,res将扩展为空,您将看到错误。
你可以使用arithmetic expression

$ (( res=s2-s1 ))
$ echo $res
1


算术上下文保证结果将是一个整数,所以即使所有的术语都是未定义的,你也会得到一个整数结果(即零)。

$ (( res = whoknows - whocares )); echo $res
0


或者,您可以通过如下声明告诉shell res是一个整数:

$ declare -i res
$ res=s2-s1


这里有趣的是,赋值的右边是在算术上下文中处理的,所以不需要$来进行扩展。

fquxozlt

fquxozlt3#

我知道这个线程在这一点上已经很老了,但我想分享我写的一个函数,可以帮助实现这一点:

abs() { 
    [[ $[ $@ ] -lt 0 ]] && echo "$[ ($@) * -1 ]" || echo "$[ $@ ]"
}

字符串
这将接受任何数学/数值表达式作为参数,并返回绝对值。例如:abs-4 => 4或abs 5-8 => 3

rqmkfv5c

rqmkfv5c4#

解决方法:试着去掉减号。
1.使用sed

x=-12
x=$( sed "s/-//" <<< $x )
echo $x

12

字符串
1.用parameter expansion检查第一个字符

x=-12
[[ ${x:0:1} = '-' ]] && x=${x:1} || :
echo $x

12


这个语法是ternary opeartor。冒号':'是do-nothing指令。
1.或者用“-”符号替换为空(再次参数扩展)

x=-12
echo ${x/-/}

12


就个人而言,当我想到string-first时,脚本bash对我来说似乎更容易。

67up9zun

67up9zun5#

我把this solution翻译成bash。我更喜欢它,而不是接受的字符串操作方法或其他条件,因为它将abs()过程保持在数学部分中

abs_x=$(( x * ((x>0) - (x<0)) ))

x=-3
abs_x= -3 * (0-1) = 3

x=4
abs_x= 4 * (1-0) = 4

字符串

yh2wf1be

yh2wf1be6#

对于纯粹主义者来说,假设bash和相对较新的一个(我在4.2和5.1上测试过):

abs() {
  declare -i _value
  _value=$1
  (( _value < 0 )) && _value=$(( _value * -1 ))
  printf "%d\n" $_value
}

字符串

eyh26e7m

eyh26e7m7#

如果你不关心数学,只关心结果,你可以使用

echo $res | awk -F- '{print $NF}'

字符串

ijnw1ujt

ijnw1ujt8#

最简单的解决方案:

res="${res/#-}"

字符串
如果-位于第一个#字符处,则仅删除一个/匹配项。

piah890a

piah890a9#

这个简单的方法适用于浮点数:
第一个月

相关问题