0

指定された数値を合計するシェルスクリプトを作成しようとしました。指定されたパラメーターがない場合、パイプ出力を読み取ろうとしますが、エラーが発生します。

#!/bin/sh

sum=0

if [ $# -eq 0 ]
then
  while read data
  do
    sum=`expr $sum + $data`
  done
else
  for ((  i = 1 ;  i <= $#;  i++  ))
  do
    sum=`expr $sum + ${!i}`
  done
fi

echo $sum

これは機能します:sum 10 12 13 しかし、これは機能しません:echo 10 12 13| sum

前もって感謝します、

4

1 に答える 1

3

どうぞ (bashではなくsh):

#!/bin/bash

sum=0

if (( $# == 0 )); then
  # Read line by line
  # But each line might consist of separate numbers to be added
  # So read each line as an array!
  while read -a data; do
    # Now data is an array... but if empty, continue
    (( ${#data[@]} )) || continue
    # Convert this array into a string s, with elements separated by a +
    printf -v s "%s+" ${data[@]}
    # Append 0 to s (observe that s ended with a +)
    s="${s}0"
    # Add these numbers to sum
    (( sum += s ))
  done
else
    # If elements come from argument line, do the same!
    printf -v s "%s+" $@
    # Append 0 to s (observe that s ended with a +)
    s="${s}0"
    # Add these numbers to obtain sum
    (( sum = s ))
fi

echo $sum

次のように呼び出すことができます。

$ echo 10 12 13 | ./sum
35
$ ./sum 10 12 13
35
$ # With several lines and possibly empty lines:
$ { echo 10 12 13; echo; echo 42 22; } | ./sum
99

お役に立てれば!

編集。についてのクールなことを学ぶことにも興味があるかもしれませんIFS@人々はとを混同する傾向があることに気づきまし*bash。何を言っているのかわからない場合は、@代わりに*, を配列添え字にも使用する必要があります。マニュアルでは、二重引用符で囲まれた場合、 (または)の値で区切られた配列のすべての要素に展開bashされることがわかります。これは、次の場合に役立ちます。$*${array[*]}IFS

#!/bin/bash

sum=0

if (( $# == 0 )); then
  # Read line by line
  # But each line might consist of separate numbers to be added
  # So read each line as an array!
  while read -a data; do
    # Now data is an array... but if empty, continue
    (( ${#data[@]} )) || continue
    # Setting IFS=+ (just for the sum) will yield exactly what I want!
    IFS=+ sum=$(( sum + ${data[*]} ))
  done
else
    # If elements come from argument line, do the same!
    # Setting IFS=+ (just for the sum) will yield exactly what I want!
    IFS=+ sum=$(( $* ))
fi

echo $sum

Gniourf は教師モードを終了します。:-)

于 2012-11-11T12:50:15.423 に答える