我有d1="11"
和d2="07"
。我想将d1
和d2
转换为整数并执行d1-d2
。在UNIX中该怎么做?
d1 - d2
目前对我返回结果"11-07"
。
我有d1="11"
和d2="07"
。我想将d1
和d2
转换为整数并执行d1-d2
。在UNIX中该怎么做?
d1 - d2
目前对我返回结果"11-07"
。
标准解决方案:
expr $d1 - $d2
你也可以这样做:
echo $(( d1 - d2 ))
但请注意,这将把07
视为八进制数字!(因此07
与7
相同,但010
与10
不同)。
echo $((d1-10#$d2))
注意:这与 echo $((d1-10#d2))
不同。 - Luchosteinnounset
和errexit
(您应该始终使用),请小心。我在我的答案https://dev59.com/1Wgu5IYBdhLWcg3wgnVh#59781257中为不同情况编写了许多测试。 - Bruno Bronoskynounset
通常是个好主意。但是你绝对不应该使用 errexit
。 - William Pursellbc
可能是最简单的解决方案。$ echo "$d1 - $d2" | bc
使用 awk
:
$ echo $d1 $d2 | awk '{print $1 - $2}'
使用 perl
:
$ perl -E "say $d1 - $d2"
使用 Python
:
$ python -c "print $d1 - $d2"
所有返回
4
expr
、awk
、bc
和dc
是否存在错误或特性,但是所有这些工具都将d1=09
作为十进制值9处理。然而,perl
和python
将其视为语法错误。对于d1=010
的情况,您会得到不同的结果。 - William Pursellecho $((d1-10#$d2))
。 - Luchostein这个问题的标题吸引了很多人,所以我决定为其他人回答这个问题,因为原问题描述的情况太过狭窄。
我最终决定编写一个函数。
0
:int(){ printf '%d' ${1:-} 2>/dev/null || :; }
int(){ expr 0 + ${1:-} 2>/dev/null||:; }
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
# This is a combination of numbers 1 and 2
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
||:
(也称作 or true
)但是保留 ;
。
# Wrapped in parens to call a subprocess and not `set` options in the main bash process
# In other words, you can literally copy-paste this code block into your shell to test
( set -eu;
tests=( 4 "5" "6foo" "bar7" "foo8.9bar" "baz" " " "" )
test(){ echo; type int; for test in "${tests[@]}"; do echo "got '$(int $test)' from '$test'"; done; echo "got '$(int)' with no argument"; }
int(){ printf '%d' ${1:-} 2>/dev/null||:; };
test
int(){ expr 0 + ${1:-} 2>/dev/null||:; }
test
int(){ expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null||:; }
test
int(){ printf '%d' $(expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null)||:; }
test
# unexpected inconsistent results from `bc`
int(){ bc<<<"${1:-}" 2>/dev/null||:; }
test
)
int is a function
int ()
{
printf '%d' ${1:-} 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '0' from '6foo'
got '0' from 'bar7'
got '0' from 'foo8.9bar'
got '0' from 'baz'
got '0' from ' '
got '0' from ''
got '0' with no argument
int is a function
int ()
{
expr 0 + ${1:-} 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '' from '6foo'
got '' from 'bar7'
got '' from 'foo8.9bar'
got '' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument
int is a function
int ()
{
expr ${1:-} : '[^0-9]*\([0-9]*\)' 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '6' from '6foo'
got '7' from 'bar7'
got '8' from 'foo8.9bar'
got '' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument
int is a function
int ()
{
printf '%d' $(expr ${1:-} : '[^0-9]*\([0-9]*\)' 2>/dev/null) || :
}
got '4' from '4'
got '5' from '5'
got '6' from '6foo'
got '7' from 'bar7'
got '8' from 'foo8.9bar'
got '0' from 'baz'
got '0' from ' '
got '0' from ''
got '0' with no argument
int is a function
int ()
{
bc <<< "${1:-}" 2> /dev/null || :
}
got '4' from '4'
got '5' from '5'
got '' from '6foo'
got '0' from 'bar7'
got '' from 'foo8.9bar'
got '0' from 'baz'
got '' from ' '
got '' from ''
got '' with no argument
我深入研究这个问题,是因为被接受的答案与set -o nounset
(也称为set -u
)不兼容。
# This works
$ ( number="3"; string="foo"; echo $((number)) $((string)); )
3 0
# This doesn't
$ ( set -u; number="3"; string="foo"; echo $((number)) $((string)); )
-bash: foo: unbound variable
let d=d1-d2;echo $d;
这应该会有所帮助。
d=$(( d1 - d2 )); echo "$d"
(但需要注意的是,以 0
为前缀的数字会被解释为_八进制_)。 - mklement0#include <stdlib.h>
#include <string.h>
int main()
{
const char *d1 = "11";
int d1int = atoi(d1);
printf("d1 = %d\n", d1);
return 0;
}
等等。