比较所有行不在同一列中的两个字段

时间:2019-03-09 17:06:05

标签: loops awk compare

我的问题如下所示: compare two fields not in the same column in consecutive lines

但是,不同之处是我想使用awk对所有行而不是仅连续行执行该操作。

感谢您的帮助!

编辑: 例如 , 我要标记$ 2 == $ 4(另一行)和$ 3 == $ 5(另一行)的行 起始文件是:

c3 1 63072 1 63072
c3 18109 29942 13125 25007
c3 18105 26056 14949 22881
c3 19004 26038 18102 25145
c3 14949 22881 18105 26056
c3 18102 25145 19004 26038
c3 18090 26038 13562 21528
c3 18964 26028 18532 25565
c3 14162 21991 10076 17931
c3 18964 26038 9921 17008

以及我希望得到的结果:

c3 1 63072 1 63072 Not_Equal
c3 18109 29942 13125 25007 Not_Equal
c3 18105 26056 14949 22881 Not_Equal
c3 19004 26038 18102 25145 Not_Equal
c3 14949 22881 18105 26056 Equal
c3 18102 25145 19004 26038 Equal
c3 18090 26038 13562 21528 Not_Equal
c3 18964 26028 18532 25565 Not_Equal

因为第5行与第3行相同,而第6行与第4行相同。 (我希望这种比较适用于第一列相同的部分 -下面的示例

说明:

c3 1 63072 1 63072 Not_Equal
c3 18109 29942 13125 25007 Not_Equal
c3 18105 26056 14949 22881 Not_Equal
c3 19004 26038 18102 25145 Not_Equal
c3 14949 22881 18105 26056 Equal
c3 18102 25145 19004 26038 Equal
c3 18090 26038 13562 21528 Not_Equal
c3 18964 26028 18532 25565 Not_Equal
a3 1 63072 1 63072 Not_Equal
a3 13125 25007 18109 29942 Not_Equal

所以即使最后一行与第二行相同,但由于第一列不同,所以不相等

1 个答案:

答案 0 :(得分:0)

请您尝试一次(仅在给定示例中进行了测试)。

第一栏没有检查条件: 此代码的Input_file中未考虑具有c / a值的第一栏。

awk '
FNR==NR{
  a[++count]=$0
  next
}
{
  for(i=1;i<=FNR;i++){
    split(a[i],array," ")
       if($3==array[1] && $2==array[4] && i!=FNR){
           print $0,"Equal"
           next
       }
  }
}
{
  print $0,"NOT Equal"
}'   Input_file  Input_file

代码如何工作:

  • 它将读取Input_file 2次。
  • 它将在第一次运行Input_file时将行的完整值保存到数组中。
  • 然后在第二次运行中,它将为每行从1到直到row的值运行一个循环(因此,这样做应该覆盖所有行,直到所有行检查为止。
  • 添加了一个特殊条件(请确保在检查当前行的第三列是否等于数组的第一项(实际上是我们在Input_file的第一轮中保存的第一字段值)并且第二字段等于第4项数组(存储在Input_file的第1次运行中的第4行行)。如果我们仔细观察,您的第一行就有1 63072 1 63072,其中第1个字段等于第3个字段,第2个到第4个SO因此我添加了此匹配项的条件不要在同一行上执行,以避免此处出现此类“假阳性”。

输出如下。

1 63072 1 63072 NOT Equal
18109 29942 13125 25007 NOT Equal
18105 26056 14949 22881 NOT Equal
19004 26038 18102 25145 NOT Equal
14949 22881 18105 26056 Equal
18102 25145 19004 26038 Equal
18090 26038 13562 21528 NOT Equal
18964 26028 18532 25565 NOT Equal
14162 21991 10076 17931 NOT Equal
18964 26038 9921 17008 NOT Equal

EDIT(在条件检查中添加$ 1): :由于OP也希望检查$ 1(具有c / a等值),因此现在也添加该条件检查。

awk '
FNR==NR{
  a[++count]=$0
  b[$1]=$1
  next
}
{
  for(i=1;i<=FNR;i++){
    split(a[i],array," ")
       if(b[$1]==array[1] && $4==array[2] && $2==array[4] && i!=FNR){
           print $0,"Equal"
           next
       }
  }
}
{
  print $0,"NOT Equal"
}'  Input_file  Input_file

输出如下。

c3 1 63072 1 63072 NOT Equal
c3 18109 29942 13125 25007 NOT Equal
c3 18105 26056 14949 22881 NOT Equal
c3 19004 26038 18102 25145 NOT Equal
c3 14949 22881 18105 26056 Equal
c3 18102 25145 19004 26038 Equal
c3 18090 26038 13562 21528 NOT Equal
c3 18964 26028 18532 25565 NOT Equal
a3 1 63072 1 63072 NOT Equal
a3 13125 25007 18109 29942 NOT Equal



通用解决方案,从两者(从上到下,从下到上)读取Input_file:

再添加1个GENERIC解决方案(上述答案的增强)。我只是想如果A=B为TRUE,那么B=A也为TRUE。表示OP的示例仅检查从第一行到最后一行。表示如果第3行的元素(第1列等于第5行的第3列),那么对于第5行的第1列到第3行第3列的条件应该为TRUE,因此现在它们都应该写为EQUAL,如果这可以帮助您然后尝试跟随。

第一栏没有检查条件: 在此代码的Input_file中未考虑具有c / a值的第一栏。

awk '
FNR==NR{
  a[++count]=$0
  next
}
{
  for(i=1;i<=count;i++){
    split(a[i],array," ")
       if($3==array[1] && $2==array[4] && i!=FNR){
           print $0,"Equal"
           next
       }
  }
}
{
  print $0,"NOT Equal"
}'  Input_file Input_file

EDIT(在条件检查中添加$ 1): :由于OP也想比较$ 1(具有c / a等值),因此现在也更改了解决方案

awk '
FNR==NR{
  a[++count]=$0
  b[$1]=$1
  next
}
{
  for(i=1;i<=count;i++){
    split(a[i],array," ")
       if(b[$1]==array[1] && $4==array[2] && $2==array[4] && i!=FNR){
           print $0,"Equal"
           next
       }
  }
}
{
  print $0,"NOT Equal"
}'  Input_file  Input_file

输出如下。

c3 1 63072 1 63072 NOT Equal
c3 18109 29942 13125 25007 NOT Equal
c3 18105 26056 14949 22881 Equal
c3 19004 26038 18102 25145 Equal
c3 14949 22881 18105 26056 Equal
c3 18102 25145 19004 26038 Equal
c3 18090 26038 13562 21528 NOT Equal
c3 18964 26028 18532 25565 NOT Equal
a3 1 63072 1 63072 NOT Equal
a3 13125 25007 18109 29942 NOT Equal