需要使用 awk 基于具有多对一关系的两列来过滤数据

需要使用 awk 基于具有多对一关系的两列来过滤数据

我有一个大文件,有 50 列和 100K 行,由 | 分隔。现在 $2(col 2) 具有多种类型的 $1(col 1) 值,这意味着 col 2 将重复。所以我已经对文件进行了排序。我现在需要根据以下条件提取/过滤结果文件: $1 是第 1 列 $2 是第 2 列

$2 和 $1 之间存在一对多关系

条件 1 :当 $2 具有 $1 两种类型时($2 的 $1 值大于 8000 且小于 8000),则选择给定 $2 的 $1 < 8000 的完整行(第 2 列)

条件 2:如果 $2 只有 $1 >= 8000,则选择完整的行,其中 $1 是给定 $2(第 2 列)中最小的行 例如:源文件 在下面的示例中,我们有 3 种类型的 $2(1234,123 和 456)现在 1234 在第 1 列中有 3 种类型的值 ($1),意味着大于和小于 8000。因此,我们为 $1<8000 的值选择了完整的行。

对于 123 和 465,我们第 1 列的值仅大于 8000($1>80000),因此我们选择了最新的行(基于第 8 列的值较高)。

样本文件

  4000|1234||||||23
    5000|1234||||||40
    9000|1234||||||25
    10000|123|||||||21
    9000|123|||||||22
    22000|456|||||||27
    15000|456|||||||29

结果文件将有:

4000|1234||||||23
5000|1234||||||40

9000|123|||||||22

15000|456|||||||29

请指教。提前致谢。

答案1

尝试(你是你的文件)

sort -n -t\| -k2 -k1 < u |
awk -F\| '$1 < 8000 { a[$2]++ ; print } 
          $1 >= 8000 { if ( !a[$2] && ( !e[$2] || e[$2]<$8 ))  {u[$2]=$0;e[$2]=$8;} ; } 
          END { for ( i in u ) print u[i] ;}'

给出

4000|1234||||||23
5000|1234||||||40
15000|456||||||29
9000|123||||||22

在哪里

  • -t\|-F\|指示 sort 和 awk 用作|分隔符
  • -k2 -k1:按第二个字段排序,然后按第一个字段排序
  • |排序行中应该是行中的最后一个字符
  • $1 < 8000 { a[$2]++ ; print }如果低于 8000,则打印行并记住 2 美元的值
  • $1 >= 8000 { ... }如果高于,则存储最高值
  • END { for ( i in u ) print u[i] ;}退出时转储所有值

  • 您可能需要重新排序。

  • 第 2 行条件可以简化(通过将 if 条件置于 {} 之外)

  • 您的测试中的某些行有 9 个字段。

请注意,该命令可以是一行

... | sort -n -t\| -k2 -k1  | awk -F\| '...'

相关内容