AWK比较2个csv文件

AWK比较2个csv文件,csv,unix,awk,diff,Csv,Unix,Awk,Diff,需要帮助比较2个csv文件。列数未知 文件1 文件2 期望输出 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'

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

文件1

文件2

期望输出

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---"}}'
文件2:

A,B,C,D,E,F,G
1,2,3,1,4,6,7
7,6,5,2,3,2,1
A,B,C,D,E,F,G
1,2,3,4,5,5,7
7,6,6,4,3,2,1
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---"
    }
}
解释:

A,B,C,D,E,F,G
1,2,3,1,4,6,7
7,6,5,2,3,2,1
A,B,C,D,E,F,G
1,2,3,4,5,5,7
7,6,6,4,3,2,1
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---"
    }
}
  • 粘贴-d'\n“file1 file2
    将交错两个输入文件
输出:(用于我的2个输入文件)

  • sed'1d'
    删除双标题
  • awk
    将头行保存在
    header
    数组中;然后每2行取2行,遍历所有字段并将它们保存在2个数组中
    l1
    l2
    ,然后我们逐个比较这2个数组的元素,一旦有第一个差异,我们就打印它,如果我们已经打印了一个差异,那么
    p
    将变为
    0
    ,并且我们将更改针对遇到的新差异打印的输出
最终输出:(对于我的2个输入文件)

awk代码格式为-F',':

A,B,C,D,E,F,G
1,2,3,1,4,6,7
7,6,5,2,3,2,1
A,B,C,D,E,F,G
1,2,3,4,5,5,7
7,6,6,4,3,2,1
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---"
    }
}
输出: 说明: 向每个文件和排序结果添加行号

( 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,因为我们需要原始内容而不是编号,编号用于排序)

由于我们已经完成了初始排序,我们可以查看差异的奇偶线 将奇数行拆分为一个称为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]}}' }}'
输出
你试了什么?在询问之前,先做一些努力,或者我应该说几乎是为了一个答案而排序……两个文件中的列数和列名是否相同?是的,两个文件中的列数相同,列数也相同。我尝试了sdiff-s-w 2000 file1 file2>file3我的答案解决了您的问题吗?;-)感谢您提供的快速解决方案,但如果存在超过1个差异,它将不起作用,它仅显示1个,并且还显示第一次出现的差异。是否要打印所有差异???好的,我可以帮你修好我以为你不需要它lolI已经相应地编辑了我的答案你能试试底部的最后一个命令吗?@Allan,我相信如果你将awk中的
getline
更改为
getline
或将
file2
作为变量,你可以去掉粘贴。谢谢你的提示!)我将尝试使用它并在明天的时间编辑它以休息:)1)首先向每个文件添加行号,2)排序t将相同的行号放在一起,3)将第一行拆分为列数组,4)创建2个dim数组(每个文件的数组5)如果行是奇数,请在数组上运行并检查列的差异,6)如果不同的打印到屏幕和更新CNT,请编辑您的答案,以解释答案中的代码。通常
awk'{if(foo)bar}
更习惯于使用
awk'foo{bar}
,除非您特别需要
else
分支(有时甚至需要)。
 {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