使用 awk 根据另一列的值对一列的值求和

jak*_*ake 98 awk

我正在尝试使用awk. 我只想对“smiths”的第 3 列求和,总共得到 212。我可以使用awk但不仅仅是“smiths”来对整个列求和。我有:

awk 'BEGIN {FS = "|"} ; {sum+=$3} END {print sum}' filename.txt
Run Code Online (Sandbox Code Playgroud)

我也在使用腻子。感谢您的任何帮助。

smiths|Login|2
olivert|Login|10
denniss|Payroll|100
smiths|Time|200
smiths|Logout|10
Run Code Online (Sandbox Code Playgroud)

Wil*_*ard 124

awk -F '|' '$1 ~ /smiths/ {sum += $3} END {print sum}' inputfilename
Run Code Online (Sandbox Code Playgroud)
  • -F标志设置字段分隔符;我把它放在单引号中,因为它是一个特殊的 shell 字符。
  • 然后$1 ~ /smiths/将以下 {code block} 仅应用于第一个字段与 regex 匹配的行/smiths/
  • 其余的与您的代码相同。

请注意,由于您在这里并没有真正使用正则表达式,只是一个特定的值,因此您可以轻松地使用:

awk -F '|' '$1 == "smiths" {sum += $3} END {print sum}' inputfilename
Run Code Online (Sandbox Code Playgroud)

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

  • 顺便说一下,我最喜欢的 awk 参考是 http://www.grymoire.com/Unix/Awk.html。非常有帮助的页面。 (5认同)
  • 谢谢@通配符!根据您的建议,我能够巧妙地聚合大 zip 存档中特定文件的未压缩大小:) `unzip -lv /appl/tmp/data.lar | grep 文档库 | awk '{sum += $1} END {打印 sum/1024/1024}'` (2认同)

And*_*rey 34

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

awk -F '|' '{a[$1] += $3} END{print a["smiths"]}' filename.txt
Run Code Online (Sandbox Code Playgroud)

作为副作用,该数组存储所有其他值:

awk -F '|' '{a[$1] += $3} END{for (i in a) print i, a[i]}' filename.txt
Run Code Online (Sandbox Code Playgroud)

输出:

smiths 212
denniss 100
olivert 10
Run Code Online (Sandbox Code Playgroud)


Rob*_*rtL 5

到目前为止非常好。您需要做的就是在块之前添加一个选择器来添加总和。这里我们检查第一个参数是否只包含“smiths”:

awk 'BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}'
Run Code Online (Sandbox Code Playgroud)

您可以通过将字段分隔符指定为选项来缩短此时间。在awk命令行上初始化变量通常是一个好主意:

awk -F'|' '$1 ~ /^smiths$/ {sum+=$3} END {print sum}'
Run Code Online (Sandbox Code Playgroud)