Linux shell逐行处理文本求和,我人傻了...
作者:守望,Linux应用开发者,目前在公众号【编程珠玑】 分享Linux/C/C++/数据结构与算法/工具等原创技术文章和学习资源。
1 12
2 23
3 34
4 56
awk '{s+=$2} END {print s}' test.data
尝试一
#!/usr/bin/env bash
sum=0
cat test.data | while read line
do
temp_num=$(echo "$line" | cut -d ' ' -f 2)
sum=$(( $sum + $temp_num ))
done
echo "we get sum:$sum"
we get sum:0
$ shellcheck myscript
Line 3:
cat test.data | while read line
^-- SC2002: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
^-- SC2162: read without -r will mangle backslashes.
Line 6:
sum=$(( $sum + $temp_num ))
^-- SC2030: Modification of sum is local (to subshell caused by pipeline).
^-- SC2004: $/${} is unnecessary on arithmetic variables.
^-- SC2004: $/${} is unnecessary on arithmetic variables.
Line 8:
echo "we get sum:$sum"
^-- SC2031: sum was modified in a subshell. That change might be lost.
$
尝试二
#!/usr/bin/env bash
sum=0
for line in $(cat test.data)
do
echo "get line :$line"
temp_num=$(echo "$line" | cut -d ' ' -f 2)
sum=$(( $sum + $temp_num ))
done
echo "we get sum:$sum"
get line :1
get line :12
get line :2
get line :23
get line :3
get line :34
get line :4
get line :56
we get sum:135
我们预期的应该是遇到换行才停止读取,为了达到这个目的,我们可以设置这个标记,即通过设置IFS来达到目的。在上面的shell开头加上:
IFS=$'\n'
尝试三
#!/usr/bin/env bash
sum=0
while read line
do
echo "line $line"
temp_num=$(echo "$line" | cut -d ' ' -f 2)
sum=$(( $sum + $temp_num ))
done < "test.data"
echo "we get sum:$sum"
当然,如果你要读取指定列,你还可以像下面这样做:
#!/usr/bin/env bash
sum=0
while read col1 col2
do
sum=$(( $sum + $col2 ))
done < "test.data"
echo "we get sum:$sum"
\n 12
\n 23
\n 34
\n 56
line
12
line
23
line
34
line
56
we get sum:125
while read -r line
总结
行中有空格,tab 行中有转义字符
Line 3:
for line in $(cat test.data)
^-- SC2013: To read lines rather than words, pipe/redirect to a 'while read' loop.
评论