我有一个非常简单的bash脚本来计算文件每行出现的数字总和(我知道有更好的方法可以做到这一点,但我实际上需要这个总和作为辅助信息,脚本应该是某种东西更多以后)。脚本如下:
TOTAL=0;
cat $DATAFILE | while read LINE;
do
COUNT=`echo $LINE| awk '{print $2;}'`;
TOTAL=$((TOTAL+COUNT));
done
echo "Total = $TOTAL";
但是,我总是得到输出“Total = 0”。令人惊讶的是,如果我在while循环中移动最后一行,我会得到正确的结果。例如,如果输入文件包含
A 5
B 3
C 6
我得到了输出
Total = 5
Total = 8
Total = 14
但是当前版本总是输出0.似乎分配给变量TOTAL的值在某种程度上会丢失。
任何人都可以帮我解决这个问题吗?
提前致谢
答案 0 :(得分:5)
这是BashFAQ #24。幸运的是,由于不必要地使用cat
,你只能在这里点击它 - 你没有充分的理由让管道在使用中。
管道的右侧(与其余内容一样,由瞬态子壳组成)在管道完成时退出,除非您shopt -s lastpipe
处于活动状态。
相反,要么添加以下行:
shopt -s lastpipe
或重构你的循环:
while read LINE;
do
COUNT=`echo $LINE| awk '{print $2;}'`;
TOTAL=$((TOTAL+COUNT));
done <"$DATAFILE"
...或者,如果真的需要从另一个进程管道,请使用进程替换:
while read LINE;
do
COUNT=`echo $LINE| awk '{print $2;}'`;
TOTAL=$((TOTAL+COUNT));
done < <(cat "$DATAFILE")
顺便说一句,如果你的shebang是#!/bin/bash
而不是#!/bin/sh
,那么写得更好如下:
total=0
while read -r _ count do;
(( total += count ))
done <"$DATAFILE"
read
可以在IFS
本身的字符上拆分行 - 您不需要使用awk
。
按照惯例,变量名称应全部为小写,除非它们代表环境变量或shell内置函数。