如果一列中的值存在于另一列中,则 ignore/delete 使用 awk 输出的行

if value from one column is present in another columns then ignore/delete the line in output using awk

我想看看 column2 值是否出现在 column3 中,反之亦然,如果这是真的,那么我想从输出中删除它。

sample.txt

3   abc def
5   ghk lmn
8   opq abc
10  lmn rst
15  uvw xyz
4   bcd abc
89  ntz uhg

到目前为止我有

awk ' {
    x[]=
    y[]=
    if (!(( in y) ||(  in x)) )
    {
     print ,,
    }


} ' sample.txt

我想要如下输出。

15  uvw xyz
89  ntz uhg

我知道 awk 逐行读取文件并且我的代码是不兼容的,因为它不检查尚未看到的未来数组索引。因此报告第一次发生。想看看这是否可以在 awk 中以更简单的方式完成,因为我的真实日期集非常庞大(多达 500 万行,400-500 兆字节)。谢谢!

一个 awk 使用输入文件两遍的想法:

awk '

# 1st pass:

FNR==NR { seen[]++           # increment our seen counter for 
          if ( != )        # do not increment seen[] if ==
             seen[]++        # increment our seen counter for 
          next
        }

# 2nd pass:

seen[] <= 1 &&               # if seen[] counts are <= 1 for both
seen[] <= 1                  #  and  then print current line
' sample.txt sample.txt

这会生成:

15  uvw xyz
89  ntz uhg

一遍又一遍地复制前 4 行,直到 sample.txt 包含约 400 万行,然后 运行 使用此 awk 脚本,生成相同的 2 行输出并使用在我的系统上大约 3 秒(VM 运行ning 在 low-end 9xxx i7 上)。


另一个 awk 使用一些额外内存但只需要一次通过输入文件的想法:

awk '
    { seen[]++
      if ( != )
         seen[]++
      if (seen[] <=1 && seen[] <= 1)
         lines[++c]=[=12=]
    }
END { for (i=1;i<=c;i++) {
          split(lines[i],arr)
          if (seen[arr[1]] <= 1 && seen[arr[2]] <= 1)
             print lines[i]
      }
    }
' sample.txt

这还会生成:

15  uvw xyz
89  ntz uhg

这个的性能将取决于唯一的 $2/$3 值的数量,因此必须是 allocated/processed 的内存量。对于我的 4 million-row sample.txt(其中 400 万行是重复行,因此使用的额外内存很少)运行 时间大约为 1.7 秒......比 2-通过解决方案(~3 秒)但对于真实世界的数据(具有大量独特的 $2/$3 值)我猜时间会更近一些。