我的第一次尝试是抓住冒号右边的东西,然后用 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
在管道中运行会将修改汇总到子外壳中,而不是当前外壳中。好吧,也在子shell中做回声:
$ cat sample.txt | grep -oP ':\D+\K\d+' | { while read n; do ((sum+=n)); done; echo $sum; }
38
这样更好,但该值仍然不在当前 shell 中。让我们尝试一些更棘手的事情
$ set -- $(cat sample.txt | grep -oP ':\D+\K\d+')
$ sum=$(IFS=+; bc <<< "$*")
$ echo $sum
38
是的,UUOC,但它是 OP 管道的占位符。