0

we have to print the old entries only Delta(Difference) in File-1 and File-2. newly added enties in files-1 no need to print.

on my unix server everyday new report is extracted from system which is later on compared with yesterday’s report.

The newly added lines in Current day report are printed by separate logic, which works perfectly.

Now My requirement is to identify the fields(for $2 check modified $4) those are updated in today’s report after comparing with yesterday’s report. So logic should run to check $2 line by line to find out $4 updated fields from File1 and print the same.

I have NR=FNR logic to do so, but its not working for below case

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

however this new logic has been getting failed for below fields combination,

file-New

7! J9AA-50! LHR! 35!
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! 15!
7! J9AA-50! LHR! 34!
8! J9BB-50! LHW! 21!

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!

with new command for compare and print. below logic fail to print expected result,

/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

this command is unnecessarily printing the lines

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

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!

Without lines 2, 3 & 5 from the current result

we have to print the updated File-Old fields(for $2 check modified $4) those are updated in today’s new report. so The logic has to become search $2 from File-Old in File-new if $2 was present in File-New then compared respective $4 values, if $4 is updated then print that line of File-Old.

can anyone please suggest the changes/new logic to get Expected output. if its not possible by using NR=FNR then how can we get it by using shell/perl script?

5
  • 1
    It's not very clear the question. Which are the newly added entries ? do you want to print the diff of the files (then why not use diff) ?
    – magor
    Commented Dec 7, 2016 at 9:01
  • 1
    Your code is obviously wrong. While reading the first file, you use FNR as an array subscript. While reading the second file, you only use two array subscripts. As a result, entries from the first file are not considered. Commented Dec 7, 2016 at 10:42
  • there is also a comm utility which can print lines only in file1, only in file2 or in both.
    – Archemar
    Commented Dec 7, 2016 at 11:08
  • It look to me that removing test3 lines, make **7! JWZZ-50! LHN! 14! 7! J9AA-50! LHR! 34! ** a new entry. You need a formal definition of "new entry".
    – Archemar
    Commented Dec 7, 2016 at 11:31
  • @Archemar the comm utility requires files that are sorted in ascending order according to its current locale Commented Oct 7, 2021 at 7:20

3 Answers 3

1
diff file_old file_new |grep '< ' |awk -F'<' '{print $2}'

7! J9AA-50! LHR! 34!
7! JWZZ-50! LHN! 14!
1
  • You can simplify the grep | awk pipeline to awk -F'^> ' 'NF>1 {print $2}. This also handles lines containing embedded > sequences Commented Oct 7, 2021 at 7:28
0

I would read in File-2, then look for lines in File-1 that are not in the array. Keep in mind that awk uses the SUBSEP variable to join strings in an array index:

awk -F'!' 'NR == FNR {f2[$2,$4]; next}  !($2 SUBSEP $4 in f2)' File-2 File-1

produces

7! J9AA-50! LHR! 35! 
7! test3! test3! 8 
7! test3! test3! 8 
7! JWZZ-50! LHN! 15! 
3
  • --> I was looking for different output than what you have suggested, on my unix server everyday new report is extracted from system which is later on compared with yesterday’s report. The newly added lines in Current day report are printed by separate logic, which works perfectly. Now My requirement is to identify the fields(for $2 check modified $4) those are updated in today’s report after comparing with yesterday’s report. So logic should run to check $2 line by line to find out $4 updated fields from File1 and print the same. can you suggest improvement. Commented Dec 8, 2016 at 17:13
  • 3
    Your question should have contained all those requirements, don't you think? The logic has to become "if ($2 was seen in File-2) and ($2,$4 was NOT seen in File-2) then print the line". Implementation left as an exercise Commented Dec 8, 2016 at 18:05
  • I made correction in my question could you please take a look now and suggest improvement. Commented Dec 9, 2016 at 4:39
0

Another awk doing a linewise comparison on fields $2 and $4

awk 'NR==FNR{f[NR]=$2$4; next}f[FNR]!=$2$4{print }' file1 file2

Output

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .