使用awk比较shell脚本中两个制表符分隔的文件

Vis*_*ain 5 command-line scripts text-processing

我已经编写了这段代码,但我面临着下面提到的问题。

我的代码是:

paste 1.txt   2.txt|
awk ' { FS = "\t " } ; NR == 1 { n = NF/2 }
              {for(i=1;i<=n;i++)
                 if($i!=$(i+n))
                   {c = c s i; s = "," }
               if(c)
                 {print "Line No. " NR-1 " COLUMN NO " c;
                  c = "" ; s = "" } } '
Run Code Online (Sandbox Code Playgroud)

预期输出:

Line No. 2 COLUMN NO 2,3
Line No. 4 COLUMN NO 1,2,3,4
Line No. 6 COLUMN NO 2,3,4,5
Line No. 7 COLUMN NO 1,2,3,4,5
Run Code Online (Sandbox Code Playgroud)

正在生成的输出:

Line No. 2 COLUMN NO 2,3
Line No. 4 COLUMN NO 1,2,3,4
Line No. 6 COLUMN NO 2,3,4,5
Line No. 7 COLUMN NO 1,2,3,4
Run Code Online (Sandbox Code Playgroud)

下面指定的文件是空格分隔的。为了更好地理解它,我以这种方式对其进行了格式化。

文件1:

ID_ID   First_name  Last_name Address                      Contact_Number
ID1     John        Rock      32, Park Lake, California    2222200000
ID2     Tommy       Hill      5322 Otter Lane Middleberge  3333300000
ID3     Leonardo    Test      Half-Way Pond, Georgetown    4444400000
ID8     Rhyan       Bigsh     6762,33 Ave N,St. Petersburg 5555500000
ID50    Steve       Goldberg  6762,33 Ave N,St. Petersburg 6666600000
ID60    Steve       Goldberg                               6666600000
Run Code Online (Sandbox Code Playgroud)

文件2:

ID_ID   First_name  Last_name   Address                      Contact_Number
ID1     John        Rock        32, Park Lake, California    2222200000
ID2     Tommy1      Hill1       5322 Otter Lane Middleberge  3333300000
ID3     Leonardo    Test        Half-Way Pond, Georgetown    4444400000
ID80    Sylvester   Stallone                                 5555500000
ID50    Steve       Goldberg    6762,33 Ave N,St. Petersburg 6666600000
ID60    Mark        Waugh       St. Petersburg               7777700000
ID70    John        Smith                                    8888800000
Run Code Online (Sandbox Code Playgroud)

Mar*_*ton 1

这是一个提示。输出:

paste 1.txt 2.txt | awk '
{ FS = "\t" }
NR == 1 { n = NF/2 } {
  for(i=1;i<=n;i++) print "\"" $i "\" " ($i == $(i+n) ? "==":"!=") " \"" $(i+n) "\""
  print "###############"
}'
Run Code Online (Sandbox Code Playgroud)

它比较并打印文件之间每条记录中的每个字段,结尾为:

"ID60" == "ID60"
"Steve" != "Mark"
"Goldberg" != "Waugh"
"" != "St. Petersburg"
"6666600000" != "7777700000"
###############
"" != "8888800000"
"ID70" != ""
"John" != ""
"Smith" != ""
"" == ""
###############
Run Code Online (Sandbox Code Playgroud)

有两个错误:

  1. 如果一行仅存在于第二个文件中,则存在隐藏的相差一错误。这是因为缺失的记录只有一个字段,即由 所添加的选项卡之前的空字符串paste。因此,在本例中,您实际上是按照 5、1、2、3、4 的顺序比较字段。

  2. 两个文件中这一行的字段 4 都是空的(尽管方式不同),所以我期望输出:

    Line No. 7 COLUMN NO 1,2,3,5

为了获得您想要的确切输出,下面的粗略修复将报告如果一行仅存在于一个文件中,则所有字段都不匹配。NF == n+1这可以通过添加到 中来检测到if,因为无论是哪个文件,都应该仅存在n+1而不是2*n仅存在于一个文件中的行的字段。

paste 1.txt 2.txt | awk '
{ FS = "\t" }
NR == 1 { n = NF/2 } {
  for(i=1;i<=n;i++) if(NF == n+1 || $i!=$(i+n)) {c = c s i; s = "," }
  if(c){print "Line No. " NR-1 " COLUMN NO " c; c = "" ; s = "" }
}'
Run Code Online (Sandbox Code Playgroud)

这假设所有记录都包含正确数量的选项卡n-1