Shell脚本逻辑NR == FNR在案例2中失败

时间:2016-12-02 05:40:53

标签: bash shell unix awk

我有两个文件名称为1)File-New 2)File-Old。它们包含如下所示的数据,

案例1

文件 - 新

7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 35!
8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 22!
7! JWZZ-102225-A-MOM-50! RZFIF RR KRT FLR W/Z LH! 15!

文件-旧

7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 34!
8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 21!
7! JWZZ-102225-A-MOM-50! RZFIF RR KRT FLR W/Z LH! 14!

当我们为两个文件运行awk -F"!" 'NR==FNR{++a[$2,$4];next} !(a[$2,$4])'逻辑时,预期输出为,

$ /usr/xpg4/bin/awk -F"!" 'NR==FNR{++a[$2,$4];next} 
                           !(a[$2,$4])' "File-New" "File-Old"

   7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 34!
   8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 21!
   7! JWZZ-102225-A-MOM-50! RZFIF RR KRT FLR W/Z LH! 14!

从输出中我们可以看到命令-F"!" 'NR==FNR{++a[$2,$4];next} !(a[$2,$4])'的逻辑被写入以打印“File-Old”中的差异。但如果两个文件的数据如下所示发生变化,则上述逻辑失败,

案例2

文件 - 新

7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 35!
8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 22!
7! JWZZ-102225-A-MOM-50! RZFIF RR KRT FLR W/Z LH! 15!
7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 34!
8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 21!

文件的旧

7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 34!
8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 21!
7! JWZZ-102225-A-MOM-50! RZFIF RR KRT FLR W/Z LH! 14!
7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 34!
8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 21!

案例2

运行相同的逻辑
$ /usr/xpg4/bin/awk -F"!" 'NR==FNR{++a[$2,$4];next} 
                           !(a[$2,$4])' "File-New" "File-Old"

   7! JWZZ-102225-A-MOM-50! RZFIF RR KRT FLR W/Z LH! 14!

预期

  7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 34!
  8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 21!
  7! JWZZ-102225-A-MOM-50! RZFIF RR KRT FLR W/Z LH! 14!

是否有人能够在逻辑 -F“中建议我需要更改的内容!” 'NR == FNR {++ a [$ 2,$ 4]; next}!(a [$ 2,$ 4])',无需更改文件即可获得案例2 的预期输出订购“File-New”“File-Old”。

注意:我们必须保持文件顺序传递给命令是修复,即“File-New”“File-Old”

1 个答案:

答案 0 :(得分:1)

您正在使用的awk代码段构造一个字典,其键的值等于第二个和第四个字段的值(使用"!"分隔的字段)。它无法达到您的预期,例如,对于此行(" File-new"中的第二行):

8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 22!

此行的哪些更改

8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 21!

" File-old"还有另一行。相同的第2和第4个字段。因此,数组[J9BB-103365-A-BOM-50,21]的键a的值不为零,因此不会打印该行。如果您希望监控这两个字段中每行的更改,您还必须将行号存储在数组中,从而产生以下结果:

awk -F'!' 'NR==FNR{++a[$2,$4,FNR];next} 
                       !(a[$2,$4,FNR])' "File-New" "File-Old"

也许您希望通过打印行号来完成此操作:

awk -F'!' 'NR==FNR{++a[$2,$4,FNR];next} 
          !(a[$2,$4,FNR]){printf "Line %d changed: %s\n", FNR, $0}' "File-New" "File-Old"

输出:

Line 1 changed: 7! J9AA-104445-A-BOM-50! REINF RR KIT FLR S/M LH! 34!
Line 2 changed: 8! J9BB-103365-A-BOM-50! MBR REINF  FLR SD LH! 21!
Line 3 changed: 7! JWZZ-102225-A-MOM-50! RZFIF RR KRT FLR W/Z LH! 14!