Reputation: 31
I have two files in my Unix server. File-Old which created yesterday and File-New created Today. Both file contains line in same format. Every field is separated by ! in each line. Example shown below.
File-Old
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!
File-New
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!
Everyday some new lines gets added to the report & some of existing lines field $4 updated (say 34 updated to 35).
I want to print only same $2 with updated $4 in old file after compared with new file.
File-Old and File-New Comparison shown below
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
we have to create a logic in which, take $2 from File-Old, search and compare it with $2 in File-New. If File-Old $2 == File-New $2, only then compare same line File-Old $4 with same line File-New $4. If File-Old $4 is != File-new $4 then print complete line of File-Old.
The file comparison logic I have with me is,
/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
Current Result,
7! J9AA-50! LHR! 34!
8! J9BB-50! LHW! 22!
7! test3! test3! 8!
7! JWZZ-50! LHN! 14!
7! J9AA-50! LHR! 34!
Expected Result:
7! J9AA-50! LHR! 34!
7! JWZZ-50! LHN! 14!
As shown above in file comparison only two lines are updated and those are 7! J9AA-50! LHR! 34! 7! JWZZ-50! LHN! 14! Only these two lines are expected to be printed, however our command is unnecessarily printing the extra lines
7! J9AA-50! LHR! 34!
8! J9BB-50! LHW! 22!
7! test3! test3! 8!
can anyone please suggest the required changes/new logic to get Expected output. if its not possible by using NR=FNR then how can we get it by using shell script?.
Upvotes: 2
Views: 215
Reputation: 1207
Words are hard especially when they are not your own.
Your actual question is not clear to me,
Are there always the same number of rows in each file?
Are the rows expected in the same order?
Does the line number a difference is at matter?
Using only your first example:
awk -F'!' 'NR==FNR{a[$2]=$4} NR!=FNR{if(a[$2]!=$4)print}' File-New File-Old
7! JWZZ-50! LH! 14!
Will expose "Old" elements which are not represented by their last occurrence in the "New" file without regard to their position in the old file
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!
Will expose the difference for corresponding rows in each file
neither of these cases result in what you indicate you expect
Edit, another case:
expose elements in the Old file which did not match any occurrence in the new file without regard to row position in either file
awk -F'!' 'NR==FNR{a[$2]=a[$2] " " $4} NR!=FNR{if(!match(a[$2],$4))print}' New Old
here we collect the values of $4 associated with $2 in the first file
then see if $4 from the second file exists in the set previously collected.
Depending on the values of $4 you may need to guard against false positives where a the match is only on a fragment,
EDIT for question change
the Question has been edited (shortened) the input files are redone and there is an annotated list of desired results but there is still no example output result so still can not be sure what is wanted.
suggest trying diff
diff -d 'File-Old' 'File-New' | grep "^<" | cut -c 3-
7! J9AA-50! LHR! 34!
7! JWZZ-50! LHN! 14!
Upvotes: 1