命令行-Unix实用程序,对保存项下的数据求和



我有一个小问题想问:

所以我有一个名为"quest"的文件,它有:

汤姆100约翰10汤姆100

如何使用awk输出类似的内容

Tom 200

我很感激你的帮助。我试着在网上查找,但我不确定我在找什么。谢谢!!

我知道如何使用正则表达式/Tom/grep作为条目,但我不知道如何从那里开始。

您可以尝试以下操作:

$ awk '{
for(i=1; i<=NF; i+=2)
    names[$i] = ((names[$i]) ? names[$i]+$(i+1) : $(i+1))
}
END{
    for (name in names) print name, names[name]
}' quest
Tom 200
John 10

您基本上对字段进行迭代,为所有奇数字段创建键,并为它们分配偶数字段的值。如果键已经存在,则只需将其添加到现有值中即可。

这要求您的文件格式在奇数字段(例如1、3、5..等)上具有名称,在偶数字段(例如2、4、6..等)中具有值。

END块中,您只需打印整个数组内容。

我想你需要计算所有用户的标记,而不仅仅是Tom,这是代码:

xargs -n2 < file|awk '{a[$1]+=$2}END{for (i in a) print i,a[i]}'
Tom 200
John 10

和一行awk

awk '{for (i=1;i<=NF;i+=2) a[$i]+=$(i+1)}END{for (i in a) print i,a[i]}' file
Tom 200
John 10
$ echo 'Tom 100 John 10 Tom 100' | grep -o '[0-9]*' | paste -sd+ | bc
210

grep -o '[0-9]*'产生

100
10
100

paste -sd+产生

100+10+100

CCD_ 9计算结果。

然而,这只适用于小输入,因为bc在输入大小上有限制。

在这种情况下,可以使用awk '{s+=$0}END{print s}'而不是paste -sd+ | bc

但要注意的是,GNU Awk将所有数字都视为浮点,当数字过大时会产生不准确的结果。

awk '/Tom/{
     for(i=1;i<=NF;i++)
     if($i=="Tom")s+=$(i+1);
     print "Tom",s;s=0}' your_file

测试

以下是在awk(无循环)中执行此操作的方法:

awk -v RS=" " '{n=$1;getline;a[n]+=$1} END {for (i in a) print i,a[i]}' quest
Tom 200
John 10

如果有不止一条像这样的

cat quest
Tom 100 John 10 Tom 100
Paul 20 Tom 40 John 10

然后使用gnu awk:执行此操作

awk -v RS=" |n" '{n=$1;getline;a[n]+=$1} END {for (i in a) print i,a[i]}' quest
Paul 20
Tom 240
John 20

如果你不喜欢getline

awk -v RS=" |n" 'NR%2 {n=$1;next}{a[n]+=$1} END {for (i in a) print i,a[i]}' quest

最新更新