【问题标题】:comparing values associates with same string [closed]比较值与相同的字符串相关联[关闭]
【发布时间】:2017-11-10 02:59:40
【问题描述】:

我正在尝试跨行比较第 2 列中的值与第 3 列中的值。比较不在同一行的第 2 列和第 3 列中的值之间。 比较条件为:

(1) 一行col2中的值与另一行col 3中的值进行比较,当这些行在第1列中具有相同的字符串时。

(2) 仅当第 1 列中的字符串至少重复两次时进行比较。

(3) 当两行在第 1 列中具有相同的字符串时,第 2 列中的值大于不同行中第 3 列中的值。

一个示例输入文件是:

约翰 0 100 约翰 120 200 史密斯 1 400 克拉丽丝 300 500 克拉丽丝 510 700 克拉丽丝 300 500 德克斯特 10 400 德克斯特 100 300 山姆 200 300 山姆 310 500 汤姆 100 300 布鲁斯 200 500 布鲁斯 520 900

期望的输出

约翰 0 100 约翰 120 200 克拉丽丝 300 500 克拉丽丝 510 700 克拉丽丝 300 500 山姆 200 300 山姆 310 500 布鲁斯 200 500 布鲁斯 520 900

不打印 col1 中带有“dexter”的行。 'dexter' 出现在两行中,但 col 2 中的值小于 col3 中其他行中的值,即 10 小于 300 且 100 小于 400。而带有 'bruce' 的行被打印,因为:因为 bruce 的第二行在 col 2 中有 520,大于在另一行 col3 中的 500。

我用 awk 试过了,下面是一个例子。看起来我无法弄清楚在另一行中将 col2 与 col3 进行比较,它们在 col1 中具有相同的字符串

awk -F "\t" 'NR==FNR{a[$1]++; b[$1]=$2; c[$1]=$3;next}   {for (i in b) if (a[$1] >2 && b[i]>c[i] ) print}' test.file test.file 

我也尝试过分步进行,首先只打印重复的行,然后比较相关的值。 我无法弄清楚如何比较与同一字符串关联的值。

【问题讨论】:

  • 你为什么在命令行上两次处理你的test.file?我不明白哪个规则将 dexter 排除在外!?您写道:第 2 列中的值大于第 3 列中的值,但在您的示例中,我没有看到与此匹配的一行。
  • 我明白你为什么把文件放了两次,但是@F.Hauri 的其他问题非常重要:哪个规则可以让 dexter 排除在外? 和“你写道:值第 2 列中的值大于第 3 列中的值,但在您的示例中,我没有看到与此匹配的一行。"
  • 要打印第 1 列中至少重复两次的字符,使用数组,我将文件传递了两次。我同意还有更多的方法。很抱歉在原始问题中不清楚。我需要跨行比较第 2 列和第 3 列中的值,前提是它们与第 1 列中的相同字符串相关联。
  • 不够清楚
  • 是的,我的意思是与同一个字符串相关联。抱歉,我最初的问题不清楚。

标签: perl shell unix awk


【解决方案1】:

正如您在尝试中所做的那样,我们对文件进行了两次传递。首先,我们为每个人捕获出现次数以及它们在 column_2 中的最大值和 column_3 中的最小值。对于第二遍,我们只是测试给定的打印条件。

NR == FNR {
    if (a[$1]) {
        # we've seen this value before in column_1
        # update the min and max values if necessary
        if ($2 > col2max[$1]) col2max[$1] = $2
        if ($3 < col3min[$1]) col3min[$1] = $3
    }
    else {
        # first time we've seen this value in column_1
        # initial the min and max to the current values
        col2max[$1] = $2
        col3min[$1] = $3
    }
    ++a[$1]
    next
}
a[$1] > 1 && col2max[$1] > col3min[$1]

输出:

$ awk -f a.awk file file
john    0   100
john    120 200
claris  300 500
claris  510 700
claris  300 500
sam 200 300
sam 310 500
bruce   200 500

【讨论】:

  • __/__ 用于解码 OP 的要求...
  • 我在代码中添加了一些 cmets。如果您需要更多信息来更好地理解它,请告诉我。
  • 非常感谢您提供完美运行的代码并理解我的问题。想不出分配最小值和最大值。为了更好地理解代码,您能否解释一下使用“if”和“else”。我们能不能在第一次通过时定义 col2 和 col3 的最小值和最大值,而不使用 if 和 else 语句。
  • 好问题。您说 ... 只需在第一次通过时定义 col2 和 col3 的最小值和最大值 ,这就是重点。我们必须知道它是否是第一次对于column_1 中的每个值。我们第一次知道它的方式是a[$1] 的初始值是否为0。在这种情况下(else 块),我们只需分配值。如果我们之前看到过这个值(if 块),我们只会根据需要更新更高或更低的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-23
  • 2011-08-17
  • 1970-01-01
相关资源
最近更新 更多