数字をスペースで区切る変数のセットがあります。ここで、最初の数字はスペースにつながる可能性があります。たとえば、次のようになります。
VAR=" 2 1 34 3 2 "
これらの数字をすべて追加する必要があります。最も簡単な方法は、数字の間のすべてのスペースを+
bcのパイプに置き換えることです。
forループ、貼り付け、bcを使用して実行できますが、より簡単な方法を知っている人はいますか?VAR
bash組み込み文字列置換機能を使用してbashで直接計算を実行できますか?
$ for i in $VAR;do echo $i;done|paste -sd+|bc
42
更新:すべての提案のおかげで、最終的に配列を使用するかなり短い方法が見つかりました。
$ VAR=" 2 1 34 3 2 "
$ arr=( $VAR );echo "$((${arr[@]/%/+}0))"
42
$ VAR="$VAR -14"
$ arr=( $VAR );echo "$((${arr[@]/%/+}0))"
28
$
答え1
ソース文字列には、繰り返されるスペースと先行/末尾のスペースが含まれています。
単純な空間変換は+
失敗します。
$ value=' 2 1 34 3 2 '
$ echo "${value// /+}"
++++++2+1++34+3++++2++++
繰り返される空白すべて折りたたみそして先行/末尾の空白を削除するには、引用符を持たない変数のみをエコー(またはprintf)します(IFSがデフォルトと仮定)。
value=$(echo $value)
echo "${value// /+}"
2+1+34+3+2
これはbcに提供できます。
$ echo "${value// /+}" | bc
42
必要に応じて1行にすべての内容:
value=$(echo $value); echo "${value// /+}" | bc
あるいは、sed
フィルタとして使用することもできます(追加の変数はありませんが遅い)。
echo $value | sed 's/ /+/g' | bc
以前の試みで<<<
問題が発生しました。
$ ~/bin/b44sh -c 'value=" 2 1 34 3 2 ";sed "s/ /+/g" <<<$value'
++++++2+1++34+3++++2++++
バージョン4.4からbashで。以前のバージョンでは、次のように動作しました。
~/bin/b43sh -c 'value=" 2 1 34 3 2 ";sed "s/ /+/g" <<<$value'
2+1+34+3+2
bash(およびsed)のすべてのバージョンで次のことができます(かなり強力なバージョンですが、外部ユーティリティを呼び出す - sed
)。
sed "s/ \+/+/g" <<<"0 $value 0" | tee /dev/tty | bc
0+2+1+34+3+2+0
42
純粋なシェルソリューション(交換${//}
部分としてbash、ksh、またはzshが必要)は次のとおりです。
value=$(echo $value); bc <<<"${value// /+}
もう一つあります。強い(ホームラン™)と持ち運べるバージョン:
- IFSへの変更が現在のシェルに影響を与えないようにします。サブシェルを使用してください
(…)
。 - IFSが空白の値を分割していることを確認してください(IFS = "")。
- 引用符なしで文字列が拡張されないことを確認します
*
(set -f). +
部品が(IFS = +)で接続されていることを確認してください。
( IFS=" "; set -f; set -- $value; IFS=+; echo "$*" | bc; )
機能バージョン1 -
シェルがそれを許可しない場合は、local
より遅いサブシェルを使用してください。フォーム
2 - 一部(POSIXでは正しい)は、引用符なしで使用することについて文句を言うことができます$*
。
sum(){ local IFS=" "; set -f; set -- $*; IFS=+; echo "$*" | bc; }
さまざまな方法でパラメータを追加します。
$ value=" 2 1 34 3 2 "
$ sum "$value"
42
$ sum $value # beware of glob chars *, ? and [ and of odd IFS=123 settings
42
$ sum " 2 1 34 3 2 "
42
$ sum " 2" "1 " "34 3" " 2 "
42
$ var=23
$ sum " 2" "1 " "34 3" " 2 " "$var"
65
答え2
パラメータ拡張を使用します。
#!/bin/bash
VAR=" 2 1 34 3 2 "
shopt -s extglob # Enable the `+(...)` construct.
expression=${VAR#+(\ )} # Remove leading spaces.
expression=${expression%+(\ )} # Remove trailing spaces.
bc <<< ${expression//+(\ )/+} # Replace strings of spaces by pluses.
答え3
いくつかのPerlのヒント:
$ perl -lane '$t+=$_ for @F; print $t' <<<"$var"
42
または
$ perl -pe 's/(\d)\s+(?=\d)/$1+/g' <<<"$var" | bc
42
または
$ perl -lane 'print eval join "+", @F' <<<"$var"
42
またはGNUsed
とcoreutils:
$ tr -s ' ' '+' <<<$var | sed 's/^+//; s/+$//' | bc
42
答え4
バッシュスクリプト:
$ v="2 4 7 10 3"
$ s=0
$ for i in $v
> do
> s=$((s+i))
> done
$ echo $s
26