ユーザーが複数のコマンドライン引数を合計するために使用できますが、互換性のない引数も無視するbashスクリプトをどのように作成できますか?たとえば、私のスクリプトがsumであるとします。
sum 10 -argument1 -argument2 -argument3 20
30
sum 7 -argument1 2 -argument2 1 -argument3
10
答え1
の場合、awk
合計と各個別の数値引数がシステムlong
タイプに適していると仮定し、オプションの先行記号を-
持つ10進数のシーケンスのみを考慮します。
#! /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}'
コマンドラインから各引数を取得し、1行に1つずつ印刷します。スクリプトawk
はこのデータを受け入れ、ゼロ以外の正の値を追加して、すべてのデータが受信された後に結果を印刷します。
はい
#!/bin/sh
printf "%s\n" "$@" | awk '$1 ~ /^[[:digit:]]+$/ {s+=$1} END {print s}'
./sum 1 -argument2 2 -argument4 3
6
数値パラメーターに数字のみが含まれることを保証できる場合は、$1 ~ /^[[:digit:]]+$/
検査式をから単純化できます$1+0 > 0
。