NR = FNR逻辑失败

时间:2016-12-06 04:58:26

标签: shell unix awk

我的Unix服务器上有两个文件。昨天创建的File-Old和今天创建的File-New。两个文件都包含相同格式的行。每个领域都是分开的!在每一行。示例如下所示。

文件的旧

fileContent

文件的新

7! J9AA-50! LHR! 34!
7! J9AA-50! LHR! 34!
8! J9BB-50! LHW! 22!
8! J9BB-50! LHW! 22!
7! test3! test3! 8!
7! test3! test3! 8!
7! JWZZ-50! LHN! 14!
7! J9AA-50! LHR! 34!
8! J9BB-50! LHW! 21!

每天都会在报告中添加一些新行。一些现有的线路现场4美元更新(比如34更新到35)。

与新文件相比,我想在旧文件中仅打印相同的$ 2和更新的$ 4。

File-Old和File-New Comparison如下所示

7! J9AA-50! LHR! 35!    
7! J9AA-50! LHR! 34!
7! 9JAA-60! ZHW! 31!
8! J9BB-50! LHW! 22!
8! J9BB-50! LHW! 22!
7! test3! test3! 8!
7! test3! test3! 8!
7! JWZZ-50! LHN! 15!
7! J9AA-50! LHR! 34!
8! J9BB-50! LHW! 21!

我们必须创建一个逻辑,从File-Old获取$ 2,搜索并与File-New中的$ 2进行比较。如果File-Old $ 2 == File-New $ 2,则仅将同一行File-Old $ 4与同一行File-New $ 4进行比较。如果File-Old $ 4是!= File-new $ 4则打印File-Old的完整行。

我和我的文件比较逻辑是,

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

当前结果,

7! J9AA-50! LHR! 34!        -- Updated to 35
7! J9AA-50! LHR! 34!        -- No change
7! 9JAA-60! ZHW! 31!        -- Newly added line     
8! J9BB-50! LHW! 22!        --  No change
8! J9BB-50! LHW! 22!        -- No change
7! test3! test3! 8!         -- No change
7! test3! test3! 8!         -- No change
7! JWZZ-50! LHN! 14!        --  Updated to 15
7! J9AA-50! LHR! 34!        --  No change
8! J9BB-50! LHW! 21!        --  No change

预期结果:

7! J9AA-50! LHR! 34!
8! J9BB-50! LHW! 22!
7! test3! test3! 8!
7! JWZZ-50! LHN! 14!
7! J9AA-50! LHR! 34!

如上文所示,在文件比较中只更新了两行,而且这些行都是   7! J9AA-50! LHR! 34!   7! JWZZ-50! LHN! 14! 预计只打印这两行,但是我们的命令不必要地打印额外的行

7! J9AA-50! LHR! 34!
7! JWZZ-50! LHN! 14!

任何人都可以建议所需的更改/新逻辑来获得预期的输出。如果使用NR = FNR无法实现,那么我们如何通过使用shell脚本来获取它?。

1 个答案:

答案 0 :(得分:1)

言语很难,特别是当他们不是你自己的时候 你的实际问题我不清楚,

每个文件中的行数总是相同吗? 这些行的顺序是否相同?
行号是否有区别?

仅使用您的第一个示例:

awk -F'!' 'NR==FNR{a[$2]=$4} NR!=FNR{if(a[$2]!=$4)print}' File-New File-Old 7! JWZZ-50! LH! 14!

将公开“旧”元素,这些元素在“新”文件中不会出现在最后一次出现,而不考虑它们在旧文件中的位置

awk -F'!' 'NR==FNR{a[NR,$2]=$4} NR!=FNR{if(a[FNR,$2]!=$4)print}' File-New File-Old 7! J9AA-50! LH! 34! 8! J9BB-50! LH! 21! 7! JWZZ-50! LH! 14! 7! J9AA-50! LH! 34! 8! J9BB-50! LH! 21!

将公开每个文件中相应行的差异

这些情况都不会导致您表达的预期

编辑,另一个案例:

暴露Old文件中与新文件中出现的内容不匹配的元素,而不考虑任一文件中的行位置

awk -F'!' 'NR==FNR{a[$2]=a[$2] " " $4} NR!=FNR{if(!match(a[$2],$4))print}' New Old

这里我们收集第一个文件中与$ 2相关的$ 4的值 然后看看先前收集的集合中是否存在第二个文件中的$ 4 根据$ 4的值,您可能需要防止误报,其中匹配仅在片段上,

编辑问题更改

问题已被编辑(缩短)输入文件被重做,并且有一个注释的所需结果列表,但仍然没有示例输出结果,所以仍然无法确定需要什么。 建议尝试diff

diff -d  'File-Old' 'File-New' | grep "^<" | cut -c 3-
7! J9AA-50! LHR! 34!
7! JWZZ-50! LHN! 14!