【问题标题】:awk compare consecutive rowsawk 比较连续行
【发布时间】:2015-11-25 00:14:38
【问题描述】:

这也许很简单,但我很累。感谢您的帮助。 我有一个包含两列的输入文件。在一个列中,我有一个 ID,在第二个列中,我有一个与之关联的值。我需要一个输出,其中第一列将是 ID(不允许重复),在第二列中打印平均值。 id 并不总是重复的,如果重复,它只能是连续的,并且最大重复值为 2。

输入

10;10
10;20
20;30
20;40
30;15
40;10
40;12

期望的输出

10;15
20;35
30;15
40;11

【问题讨论】:

  • 本网站上的任何问题都与此相似,您应该能够从中找出答案。
  • 很抱歉,我已经检查了其中一些,但仍然感到困惑......请提供其他帮助吗?

标签: awk compare rows


【解决方案1】:

这条单线做到了:

awk -F';' -v OFS=";" '{a[$1]+=$2+0;b[$1]++}END{for(x in a)print x,a[x]/b[x]}' file

使用您的数据进行测试:

kent$  cat f
10;10
10;20
20;30
20;40
30;15
40;10
40;12

kent$  awk -F';' -v OFS=";" '{a[$1]+=$2+0;b[$1]++}END{for(x in a)print x,a[x]/b[x]}' f
10;15
20;35
30;15
40;11

【讨论】:

  • @fedorqui 是的,我有OFS,我删除了因为我有printfOFS 使printf 更长.. :-)
  • @fedorqui 你是对的......!!我忘了a/b 会是 int .....呃...我更新它
  • 非常感谢!但是,如果我真的在输入文件中有其他列也想打印平均值怎么办?我认为将其添加到您的脚本中很容易,但我真的不知道如何...实际输入文件有 80 列作为我提到的第二个...
  • 没关系!我从你那里学到了很多东西,我很高兴有时会展示一些东西:D
  • 只要提到输出将是“随机”顺序,事实上它与上面输入的顺序相同是纯粹的巧合。为什么要在 2 美元上加零?
【解决方案2】:
$ cat tst.awk
BEGIN { FS=OFS=";" }
($1 != prev) && (NR>1) { print prev, sum/cnt; sum=cnt=0 }
{ prev=$1; sum+=$2; cnt++ }
END { if (cnt) print prev, sum/cnt }

$ awk -f tst.awk file
10;15
20;35
30;15
40;11

【讨论】:

  • 非常感谢!但是,如果我真的在输入文件中有其他列也想打印平均值怎么办?我认为将其添加到您的脚本中很容易,但我真的不知道如何...实际输入文件有 80 列作为我提到的第二列
  • 那么您应该在问题的示例输入/输出中真正显示其他列。无论您想做什么都是微不足道的,但您的评论可能意味着几件事之一。不 - 不要显示 80 列,3 或 4 列就可以了。
  • @user3666956 一些建议 - 在软件解决方案中,1 项和 2 项之间以及 2 项和 3 项之间存在天壤之别。连续项目和非连续项目之间也有天壤之别。因此,如果您要发布一个问题,请考虑如何展示一个能够捕捉您的问题的最小示例,但如果真正的问题涉及 3 个或更多项目,那么不要显示一个包含 1 个项目(甚至 2 个项目)的示例,并希望得到解决方案与 3 个或更多相同。
  • 抱歉,这是一个新手错误...我会在以后考虑这个问题,我想我需要发布一个新问题,因为你没有在这个问题上帮助我?无论如何,感谢您的建议,再次抱歉!
  • 没有人会帮助您满足您的新要求,因为您没有完成被告知您需要做的事情才能让我们为您提供帮助 - 编辑您的问题以显示更新的示例输入/输出反映这些要求。不过,现在已经很久了,我怀疑是否有人再看这个问题,所以在这一点上,您不妨将答案标记为已接受并提出一个新问题。
【解决方案3】:

(现场编写,我没有尝试过;假设 GNU awk;假设输入排序)

awk -F';' '
    BEGIN {
        id=""
    }
    $1 != id {
        if (id != "") {
            printf("%s;%d\n", id, sum/n);
            n = sum = 0;
            id = str($1);
        }
        sum += $2;
        n++;
    }
    END {
        if (n > 0) printf("%s;%s\n", id, sum/n);
    }
'

【讨论】:

  • 没有什么特定于 gawk 的,但是运行上面会产生语法错误,因为尝试在单引号分隔的脚本中使用单引号,并且在 awk 中没有名为 str() 的函数,并且您不需要虚假的尾随分号,并且 printf 是内置的,而不是函数,因此 printf args 周围的括号并没有像您认为的那样做。一旦所有这些都修复了,如果在空文件上运行,它也会失败并出现除以零错误。
  • @EdMorton 我可以忍受。正如警告的那样,我直接写了它,没有经过测试。请注意,OP 在询问之前没有尝试任何操作。我修正了最明显的错误;不知道 printf,我总是这样使用它,它就可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-26
  • 2012-10-17
相关资源
最近更新 更多