我将如何创建一个 bash 脚本,用户可以使用该脚本对任意数量的命令行参数求和,但它也会忽略不兼容的参数?例如,假设我的脚本名为 sum:
sum 10 -argument1 -argument2 -argument3 20
30
sum 7 -argument1 2 -argument2 1 -argument3
10
答案1
对于awk
,假设总和和每个单独的数字参数都适合您的系统long
类型,并且仅考虑带有可选前导-
符号的十进制数字序列:
#! /bin/sh -
awk 'BEGIN{
sum = 0
for (i = 1; i < ARGC; i++)
if (ARGV[i] ~ /^-?[0123456789]+$/)
sum += ARGV[i]
print sum}' "$@"
对于任意精度,您可以使用bc
:
#! /bin/sh -
awk 'BEGIN{
for (i = 1; i < ARGC; i++)
if (ARGV[i] ~ /^-?[0123456789]+$/)
print "s+="ARGV[i]
print "s"}' "$@" | bc
例子:
$ ./sum1 999999999999999999999999 1
999999999999999983222784
$ ./sum2 999999999999999999999999 1
1000000000000000000000000
答案2
一个(非最佳)求和示例:
echo "$@" |awk '{for (i = 1; i <= NF; i++) j+=$i} END {print j}'
(假设数字是所有awk
接受的数字)
例子:
./ff 1 2 3.1 0x10 0100
86.1
警告:任何以数字开头的单词都将被解释为数字
答案3
这是另一种可能性
printf "%s\n" "$@" | awk '$1 ~ /^[[:digit:]]+$/ {s+=$1} END {print s}'
它从命令行获取每个参数并打印它,每行一个。该awk
脚本接受此数据并将非零正值相加,在收到所有数据后打印结果
例子
#!/bin/sh
printf "%s\n" "$@" | awk '$1 ~ /^[[:digit:]]+$/ {s+=$1} END {print s}'
./sum 1 -argument2 2 -argument4 3
6
如果您可以保证您的数字参数仅包含数字,您可以将检查表达式从$1 ~ /^[[:digit:]]+$/
to简化$1+0 > 0
。