bash 数字的绝对值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29223313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:53:59  来源:igfitidea点击:

Absolute value of a number

bashshellunix

提问by Ali Sajid

I want to take the absolute of a number by the following code in bash:

我想通过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

Now the problem I am facing is in the if statement, no matter what I changes it always goes in the if, I tried to put [[ ]]around the statement but nothing.

现在我面临的问题是在 if 语句中,无论我如何更改它总是在 if 中,我试图[[ ]]绕过该语句但什么也没有。

Here is the error:

这是错误:

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

采纳答案by kojiro

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

What's actually happening on the fourth line is that resis being set to nothing and exported for the exprcommand. Thus, when you run [ "$res" -lt 0 ]resis expanding to nothing and you see the error.

第四行实际发生的res是被设置为空并为expr命令导出。因此,当您运行时[ "$res" -lt 0 ]res扩展为空并且您会看到错误。

You could just use an arithmetic expression:

您可以只使用算术表达式

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

Arithmetic context guarantees the result will be an integer, so even if all your terms are undefined to begin with, you will get an integer result (namely zero).

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

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

Alternatively, you can tell the shell that resis an integer by declaring it as such:

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

$ declare -i res
$ res=s2-s1

The interesting thing here is that the right hand side of an assignment is treated in arithmetic context, so you don't need the $for the expansions.

有趣的是,赋值的右侧是在算术上下文中处理的,因此您不需要$扩展。

回答by Suuuehgi

You might just take ${var#-}.

你可能只需要${var#-}.

${var#Pattern}Remove from $varthe shortest part of $Patternthat matches the front end of $var. tdlp

${var#Pattern}从匹配的前端$var的最短部分中删除。tdlp$Pattern$var



Example:

例子:

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

echo $s3
-1

echo ${s3#-}
1

回答by bng44270

I know this thread is WAY old at this point, but I wanted to share a function I wrote that could help with this:

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

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

This will take any mathematical/numeric expression as an argument and return the absolute value. For instance: abs -4 => 4 or abs 5-8 => 3

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