仅打印文件中具有唯一第一列和特定第三列值的行

仅打印文件中具有唯一第一列和特定第三列值的行

我有一个如下所示的文件

1,1230,add
1,1235,remove
2,1240,add
2,1245,remove
3,1250,add
4,1255,remove

我想打印第一个字段具有唯一值的那些行,其中第三个字段等于add.该示例的预期输出为

3,1250,add

或仅第一列,即

3

下面的命令给了我不同的记录,但后来我想检查第三列是否是“添加”,然后只打印输出。

awk -F ',' 'print $1' filename | uniq -u

答案1

在这种情况下,我想到了双遍方法:

awk -F',' 'NR==FNR{seen[$1]++;next} $3=="add" && seen[$1]==1' file.txt file.txt

这将处理输入文件两次(因此它作为参数被声明两次)。

  • 在第一遍中,NR全局行计数器 等于FNR每个文件行计数器,我们只计算遇到第一个字段的这个特定值的频率,否则立即跳过处理(语句next)。
  • 在第二遍中,我们检查第三个字段是否等于add,并且第一个字段仅出现一次。如果是这样,我们打印该行(因为这两个条件将计算为true)。

答案2

由于 AdminBee 已经展示了该awk方法,因此这是使用标准实用程序的另一种方法:

 sort -t',' -k1,1 file | uniq -u -w 1 | grep 'add$'
  • sort使用逗号作为分隔符并仅按字段 1 排序
  • uniq只打印唯一的行但检查不超过 1 () 每行字符
  • 现在grep以“add”结尾的行

限制:uniq当然只检查一个字符。对于字段 1 中的两位或多位数字条目,必须对字段 1 进行预处理,例如在左侧填充零,然后相应地增加用于检查的字符数。如果您的文件已按照示例中给出的方式进行排序,则可能会跳过排序。

答案3

使用 awk 一次性完成:

awk -F ',' '  
  { if ( ! seen[$1]++ )
    { if ( $3 == "add" )
        keep[$1] = $0
    }
    else
    {
      if ( keep[$1] )
        delete keep[$1]
    }
  }
  END  {
    for (i in keep)
      print keep[i]
  }'  infile

相关内容