比较两列(从一行)到另外两列(来自所有行)

时间:2016-07-05 10:21:56

标签: shell csv awk

问题1:对于 file.csv 的每一行,将第1列和第2列与第3列和第4列进行比较。所有字段用“,”分隔。
解决方案:awk 'BEGIN { FS = "," } ;{if ($1==$3 && $2==$4) print $1,$2,$3,$4,"MATCH"}; {if ($1!=$3||$2!=$4) print $1,$2,$3,$4,"UNMATCH"}' file.csv > file2.csv

上述比较是逐行进行的。

问题2:对于 file.csv 的每一行,将第1列和第2列与所有行中的第3列和第4列进行比较。如果匹配,则print $1,$2,$3,$4,"MATCH"。如果没有,则打印$1,$2,$3,$4,"UNMATCH"。请注意,$3,$4不必与$1,$2位于同一行。 如果 file.csv 具有 n 行,则输出应为 n ^ 2 行。

我们能够解决问题1.但有人可以就问题2提出建议吗?

4 个答案:

答案 0 :(得分:0)

如果您希望仅在$3$4来自同一行时才匹配, 你可以为每一行累积几对vaues,最后,对已保存的夫妇进行双循环以找到匹配。

$ cat 1234.csv 
1,2,3,4
4,5,6,7
7,7,1,2
$ awk -F, '    {V12[NR]=$1","$2;V34[NR]=$3","$4} # accumulate couples of values
           END{for(i in V12)
                   for(j in V34)
                       if(V12[i]==V34[j]) print i, j, V12[i], V34[j]}' 1234.csv
1 3 1,2 1,2
$

答案 1 :(得分:0)

问题#1测试输入:

echo "1,2,3,4
2,1,3,4
1,2,1,2" > file.csv

问题#1代码:

while IFS=, read a b c d e ; do \
    x=MATCH ; \
    [ "$a$b" != "$c$d" ] && x=UN$x ; \
    echo "$a,$b,$c,$d: $x" ; \
done < file.csv

问题#1输出:

1,2,3,4: UNMATCH
2,1,3,4: UNMATCH
1,2,1,2: MATCH

问题#2代码,(注意代码重用问题#1):

cut -d',' -f1,2 file.csv > 12.csv ; \
cut -d',' -f3,4 file.csv > 34.csv ; \
while IFS=, read a ; do \
    while read b ; do \
        echo $a,$b ; \
    done < 34.csv ; \
done < 12.csv | \
while IFS=, read a b c d e ; do \
    x=MATCH ; \
    [ "$a$b" != "$c$d" ] && x=UN$x ; \
    echo "$a,$b,$c,$d: $x" ; \
done ; \
rm 12.csv 34.csv

问题#2输出:

1,2,3,4: UNMATCH
1,2,3,4: UNMATCH
1,2,1,2: MATCH
2,1,3,4: UNMATCH
2,1,3,4: UNMATCH
2,1,1,2: UNMATCH
1,2,3,4: UNMATCH
1,2,3,4: UNMATCH
1,2,1,2: MATCH

答案 2 :(得分:0)

  

将第1列和第2列与第3和第4列中的每个字段进行比较

这是第一对列与第二对列的笛卡尔积。

您知道如何使用 awk 打印第1列和第2列。单独的调用将打印3和4.您可以使用 comm (1)查找匹配项和那两组的不匹配,并再次根据需要转换输出。

我建议在awk中使用 comm (1)覆盖循环和数组,因为它应该表现更好,并且在大输入时可以更好地扩展。有了一些聪明,你可以将整个shebang设置为管道,避免临时文件并在讨价还价中获得并行执行。

答案 3 :(得分:0)

join/awk组合,使用@ agc的输入文件

$ join -j99 -t, -o1.1,1.2,2.3,2.4 file.csv{,} | 
  awk -F, '{print $0, (($1==$3 && $2==$4)?"":"UN") "MATCH"}'

1,2,3,4 UNMATCH
1,2,3,4 UNMATCH
1,2,1,2 MATCH
2,1,3,4 UNMATCH
2,1,3,4 UNMATCH
2,1,1,2 UNMATCH
1,2,3,4 UNMATCH
1,2,3,4 UNMATCH
1,2,1,2 MATCH