我正在尝试使用awk将某些数字求和。我只想对“史密斯”的第3列求和,以得到总计212。我可以使用awk而不是“史密斯”对整个列求和。我有:

awk 'BEGIN {FS = "|"} ; {sum+=} END {print sum}' filename.txt


我也在用腻子。谢谢您的帮助。

smiths|Login|2
olivert|Login|10
denniss|Payroll|100
smiths|Time|200
smiths|Logout|10


#1 楼

awk -F '|' ' ~ /smiths/ {sum += } END {print sum}' inputfilename
标志


-F标志设置字段分隔符;我将其用单引号引起来,因为它是特殊的外壳字符。
然后 ~ /smiths/仅将以下{code block}应用于第一个字段与正则表达式/smiths/匹配的行。
其余部分与您的代码相同。

请注意,由于此处并没有真正使用正则表达式,因此只需指定一个值,就可以轻松使用:

awk -F '|' ' == "smiths" {sum += } END {print sum}' inputfilename


检查字符串是否相等。正如在另一个答案中提到的,这等效于使用正则表达式/^smiths$/,其中包括仅匹配字符串开头(字段1的开头)的^锚点和仅匹配字符串结尾的$锚点。不知道您对正则表达式有多熟悉。它们非常强大,但是在这种情况下,您可以轻松地使用字符串相等性检查。

评论


顺便说一下,我最喜欢的awk参考是grymoire.com/Unix/Awk.html。非常有用的页面。

–通配符
2015年11月14日下午5:10

谢谢@Wildcard!我能够根据您的建议整齐地将未压缩大小的特定文件压缩到大zip存档中:) unzip -lv /appl/tmp/data.lar | grep文档库| awk'{sum + = $ 1} END {print sum / 1024/1024}'

– Pawel Kruszewski
17-12-12在11:24



#2 楼

另一种方法是使用awk关联数组,更多信息在这里。该行产生所需的输出:

awk -F '|' '{a[] += } END{print a["smiths"]}' filename.txt


作为副作用,该数组存储所有其他值: br />输出:

awk -F '|' '{a[] += } END{for (i in a) print i, a[i]}' filename.txt


评论


这是正确的答案

– PoVa
18年3月24日在13:17

#3 楼

到目前为止很好。您需要做的就是在块前添加一个选择器以添加总和。在这里,我们检查第一个参数是否仅包含“铁匠”:在awk中,通常最好在命令行上初始化变量:

awk 'BEGIN {FS = "|"} ;  ~ /^smiths$/ {sum+=} END {print sum}'


#4 楼

我个人更希望使awk部分尽可能简单,并且在没有它的情况下尽可能多地执行。混合逻辑无法利用Unix流水线的功能,因此对于紧密相关的用例更难以理解,调试或修改。

cat filename.txt | perl -pe 's{.*|}{}g' | awk '{sum+=} END {print sum}'


#5 楼

cat filename.txt | grep smiths | awk -F '|' '{sum+=$NF} END {print sum}'




-F用于指定分隔符的选项。

$NF用于“最后一列”。


评论


cat和grep在这里是不必要的。

–安德烈
18年4月18日在13:29

为什么不需要grep @Andrey? OP希望仅添加“史密斯”行。您需要修改awk语句,对不对?

– E L
19年6月19日,0:27

@EL是的,如果grep调用不存在,则应将awk语句修改为/ smiths / {...}。这是一个微不足道的修改,但是它提供了很多好处:减少正在运行的进程的数量,简化错误控制,并使代码更清晰。

–安德烈
19年6月20日在13:45