繁体   English   中英

AWK比较2个CSV文件

[英]AWK to compare 2 csv files

需要帮助比较2个csv文件。 列数未知。

文件1

A,B,C,D,E,F,G
1,2,3,4,5,6,7
7,6,5,4,3,2,1

文件2

A,B,C,D,E,F,G
1,2,3,4,5,5,7
7,6,6,4,3,2,1

期望的输出

Item  FILE1   FILE2
1     F=6     F=5
7     C=5     C=6

如果有更多的列不匹配,那么输出应该是这样的。

Item  FILE1   FILE2
1     F=6     F=5
      ---     ---
      ---     ---
7     C=5     C=6

您可以使用以下命令:

paste -d '\n' file1 file2 | sed '1d' | awk -F',' 'NR==1{print "Item\tFILE1\tFILE2";for(i=1;i<=NF;i++)header[i]=$i;}NR>1{for(i=1;i<=NF;i++)l1[i]=$i;getline;for(i=1;i<=NF;i++)l2[i]=$i;p=1;for(i=1;i<=NF;i++){if(l1[i]!=l2[i])if(p){print l1[1]"\t"header[i]"="l1[i]"\t"header[i]"="l2[i];p=0;}else print " \t---\t---"}}'

文件1:

A,B,C,D,E,F,G
1,2,3,1,4,6,7
7,6,5,2,3,2,1

文件2:

A,B,C,D,E,F,G
1,2,3,4,5,5,7
7,6,6,4,3,2,1

说明:

  • paste -d '\\n' file1 file2将插入2个输入文件

输出:(用于我的2个输入文件)

A,B,C,D,E,F,G
A,B,C,D,E,F,G
1,2,3,1,4,6,7
1,2,3,4,5,5,7
7,6,5,2,3,2,1
7,6,6,4,3,2,1
  • sed '1d'删除双头
  • awk将把标题行保存在header数组中; 然后每2取2行,遍历所有字段并将它们保存在2个数组l1l2 ,然后我们将这2个数组的元素1对1进行比较,一旦我们有了第一个差异,就打印它,如果已经打印一个差异然后p变为0然后我们更改输出,以打印遇到的新差异

最终输出:(用于我的2个输入文件)

Item    FILE1   FILE2
1       D=1     D=4
        ---     ---
        ---     ---
7       C=5     C=6
        ---     ---

用-F','格式化的awk代码:

NR==1{
    print "Item\tFILE1\tFILE2";
    for(i=1;i<=NF;i++)header[i]=$i;
}
NR>1{
    for(i=1;i<=NF;i++)l1[i]=$i;
    getline;
    for(i=1;i<=NF;i++)l2[i]=$i;
    p=1;
    for(i=1;i<=NF;i++){
        if(l1[i]!=l2[i])
          if(p){
            print l1[1]"\t"header[i]"="l1[i]"\t"header[i]"="l2[i];
            p=0;
          }
          else 
            print " \t---\t---"
    }
}

如果要显示所有差异,请使用

NR==1{
    print "Item\tFILE1\tFILE2";
    for(i=1;i<=NF;i++)header[i]=$i;
}
NR>1{
    for(i=1;i<=NF;i++)l1[i]=$i;
    getline;
    for(i=1;i<=NF;i++)l2[i]=$i;
    p=1;
    for(i=1;i<=NF;i++){
        if(l1[i]!=l2[i])
          if(p){
            print l1[1]"\t"header[i]"="l1[i]"\t"header[i]"="l2[i];
            p=0;
          }
          else 
            print " \t"header[i]"="l1[i]"\t"header[i]"="l2[i];
    }
}

或在一个命令中:

paste -d '\n' file1 file2 | sed '1d' | awk -F',' 'NR==1{print "Item\tFILE1\tFILE2";for(i=1;i<=NF;i++)header[i]=$i;}NR>1{for(i=1;i<=NF;i++)l1[i]=$i;getline;for(i=1;i<=NF;i++)l2[i]=$i;p=1;for(i=1;i<=NF;i++){if(l1[i]!=l2[i])if(p){print l1[1]"\t"header[i]"="l1[i]"\t"header[i]"="l2[i];p=0;}else print " \t"header[i]"="l1[i]"\t"header[i]"="l2[i]; }}'

这将产生以下输出:

Item    FILE1   FILE2
1       D=1     D=4
        E=4     E=5
        F=6     F=5
7       C=5     C=6
        D=2     D=4
~> ( nl file1.txt && nl file2.txt ) | sort | awk 'BEGIN{cnt=1;print "Item\tFILE1\tFILE2"}{if (NR==1) split($2,col,",");}{if ((NR%2)==1){split($2,data_2_NR,",");}else {split($2,data_1_NR,",");  for (i in data_1_NR) if (data_1_NR[i]!=data_2_NR[i]) print cnt++ "-" data_1_NR[1] "\t"col[i]"="data_1_NR[i] "\t"col[i]"=" data_2_NR[i]  }}' }}'

输出:

Item    FILE1   FILE2
1-1     F=6     F=5
2-7     C=6     C=5

说明:

在每个文件中添加行号并排序结果

( nl file1.txt && nl file2.txt ) | sort | \ 

输出:

   1    A,B,C,D,E,F,G
   1    A,B,C,D,E,F,G
   2    1,2,3,4,5,5,7
   2    1,2,3,4,5,6,7
   3    7,6,5,4,3,2,1
   3    7,6,6,4,3,2,1

开始计数器(cnt),显示差异和打印表标题的数量

 awk 'BEGIN{cnt=1;print "Item\tFILE1\tFILE2"}\

从第一行获取列名称(拆分$ 2,因为我们需要原始内容,而不是编号,编号用于排序)

 {if (NR==1) split($2,col,",");}\

由于我们已经完成了初始排序,因此我们可以查看奇数行和偶数行的差异,将奇数行拆分为一个名为data_2_NR的数组

 {if ((NR%2)==1){split($2,data_2_NR,",");}\

偶数行到名为data_1_NR的数组

 else {split($2,data_1_NR,",");\

在data_1_NR和data_2_NR阵列中的所有列上运行并比较每个阵列单元

 for (i in data_1_NR) if (data_1_NR[i]!=data_2_NR[i])\

如果它们在表中是不同的打印行

 print cnt++ "-" data_1_NR[1] "\t"col[i]"="data_1_NR[i] "\t"col[i]"=" data_2_NR[i]}}' }}'

输出

Item    FILE1   FILE2
1-1     F=6     F=5
2-7     C=6     C=5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM