私の最初の試みは、コロンの右側にあるものを取得して、bash に合計させることでした。
$ sum=0
$ cat sample.txt | while IFS=: read key value; do ((sum += value)); done
bash: ((: "15": syntax error: operand expected (error token is ""15"")
bash: ((: "20": syntax error: operand expected (error token is ""20"")
bash: ((: "3": syntax error: operand expected (error token is ""3"")
0
したがって、引用符を削除する必要があります。わかりました。洗練された Perl 正規表現を使用して、コロンの右側にある最初の数字セットを抽出します。
$ cat sample.txt | grep -oP ':\D+\K\d+'
15
20
3
わかりました。
$ cat sample.txt | grep -oP ':\D+\K\d+' | while read n; do ((sum+=n)); done; echo $sum
0
は?そうそう、while
パイプラインで実行すると、変更が現在のシェルではなくサブシェルにまとめられます。さて、サブシェルでもエコーを行います:
$ cat sample.txt | grep -oP ':\D+\K\d+' | { while read n; do ((sum+=n)); done; echo $sum; }
38
その方が良いですが、それでも値は現在のシェルにはありません。もっとトリッキーなことを試してみましょう
$ set -- $(cat sample.txt | grep -oP ':\D+\K\d+')
$ sum=$(IFS=+; bc <<< "$*")
$ echo $sum
38
はい、UUOCですが、OPのパイプラインが何であれ、これはプレースホルダーです。