【问题标题】:How can I select lines in reason of a value in awk?如何根据 awk 中的值选择行?
【发布时间】:2015-09-15 17:25:32
【问题描述】:

假设我有一个结构如下的文件:

AAAA 700 something1 something_else1
AAAA 98 something2 something_else2
AAAA 2000 something3 something_else3
BBBB 200 something4 something_else4
BBBB 21 something5 something_else5
BBBB 300 something6 something_else6

我需要为 $1 列中的每个值提取 $1 列中具有最高值的整行。这意味着,对于字段 AAAA,我需要打印 $2=2000 所在的行。因此,输出应如下所示:

AAAA 2000 something3 something_else3
BBBB 300 something6 something_else6

我是用python做的,但是文件很大,过程很耗时。有没有办法用 awk 做到这一点?

【问题讨论】:

  • 您的意思是说having the highest value in column $2 而不是...in column $1

标签: bash awk fileparsing


【解决方案1】:
$ cat tst.awk
$1!=prev { if (rec!="") print rec; max=$2; rec=$0 }
$2 > max { max=$2; rec=$0 }
{ prev=$1 }
END { if (rec!="") print rec }

$ awk -f tst.awk file
AAAA 2000 something3 something_else3
BBBB 300 something6 something_else6

以上假设$1 值始终分组在一起,如您的示例输入所示。鉴于此,它一次仅在内存中存储 1 条记录(因为您说您的输入文件很大,可能很重要),以与读取记录相同的顺序打印记录,即使为零或负 $2 值也可以工作,并且不会为空输入文件输出任何内容。

【讨论】:

    【解决方案2】:

    你可以试试

    awk '
    !($1 in max) || ($2>max[$1]) {
      max[$1]=$2; a[$1]=$0;
    } 
    END{ 
      for(i in a){ 
        print a[i];
      }
    }' input_file
    

    你得到(顺序可能不同,因为它取决于 a 中的哈希):

    BBBB 300 something6 something_else6 AAAA 2000 something3 something_else3

    【讨论】:

    • $2>max[$1] 更改为!($1 in max) || ($2>max[$1]),因此max[$1]a[$1] 总是在第一次看到新的$1 值时填充。您还可以通过将条件移到操作部分之外并进入条件部分而不是在操作部分内在其周围添加if (...) 来使其更加笨拙。
    • @EdMorton 我明白了,非常感谢您的反馈
    【解决方案3】:

    sort/awk 的组合最简单

    $ sort -k1,2nr file | awk '!a[$1]++'
    
    AAAA 2000 something3 something_else3
    BBBB 300 something6 something_else6
    

    按第一个字段和第二个字段(降序)排序,让 awk 选择组的第一行(设计上最高的)。

    【讨论】:

      猜你喜欢
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多