Search code examples
awkzsh

When joining two files using awk, how does one print values for non-matching columns?


I've got a Nessus report (FILE1.csv) with a bunch of data (including CVE's / Column 7) I am comparing the list of CVE's with another list of CVE's I have corresponding patches for (FILE2.csv). I would like the report to have an additional column showing which Nessus plugins have matching CVE's from FILE2.csv.

I am using split to split the 7th column by semi-colon, then looping through each of those values and comparing it to the value from FILE2.csv, currently its only matching on the last value, I am unclear as to why.

Here is what I have currently

awk -F',' 'NR==FNR {n=split($7,x,";"); for(i=1;i<n;i++) a[x[i]]=$0; next}; $1 in a {print a[$1] ",TRUE"}' '/C/Temp/FILE1.csv' '/C/Temp/FILE2.csv'

FILE1.csv

122111,RHEL 7 : docker (RHSA-2019:0304),High,3/7/2019 8:40,4/1/2019 6:52,2/11/2019 9:00,CVE-2019-5736,0,9.3,100.111.222.1
121514,Google Chrome < 72.0.3626.81 Multiple Vulnerabilities,Critical,2/28/2019 5:00,4/1/2019 7:14,1/29/2019 9:00,CVE-2019-5754;CVE-2019-5755;CVE-2019-5756;CVE-2019-5757;CVE-2019-5758;CVE-2019-5759;CVE-2019-5760;CVE-2019-5761;CVE-2019-5762;CVE-2019-5763;CVE-2019-5764;CVE-2019-5765;CVE-2019-5766;CVE-2019-5767;CVE-2019-5768;CVE-2019-5769;CVE-2019-5770;CVE-2019-5771;CVE-2019-5772;CVE-2019-5773;CVE-2019-5774;CVE-2019-5775;CVE-2019-5776;CVE-2019-5777;CVE-2019-5778;CVE-2019-5779;CVE-2019-5780;CVE-2019-5781;CVE-2019-5782,445,10,100.111.222.2
121514,Google Chrome < 72.0.3626.81 Multiple Vulnerabilities,Critical,2/28/2019 6:24,2/28/2019 6:24,1/29/2019 9:00,CVE-2019-5754;CVE-2019-5755;CVE-2019-5756;CVE-2019-5757;CVE-2019-5758;CVE-2019-5759;CVE-2019-5760;CVE-2019-5761;CVE-2019-5762;CVE-2019-5763;CVE-2019-5764;CVE-2019-5765;CVE-2019-5766;CVE-2019-5767;CVE-2019-5768;CVE-2019-5769;CVE-2019-5770;CVE-2019-5771;CVE-2019-5772;CVE-2019-5773;CVE-2019-5774;CVE-2019-5775;CVE-2019-5776;CVE-2019-5777;CVE-2019-5778;CVE-2019-5779;CVE-2019-5780;CVE-2019-5781;CVE-2019-5782,445,10,100.111.222.3

FILE2.csv

CVE-2019-5754
CVE-2019-5755

Current Output

121514,Google Chrome < 72.0.3626.81 Multiple Vulnerabilities,Critical,2/28/2019 6:24,2/28/2019 6:24,1/29/2019 9:00,CVE-2019-5754;CVE-2019-5755;CVE-2019-5756;CVE-2019-5757;CVE-2019-5758;CVE-2019-5759;CVE-2019-5760;CVE-2019-5761;CVE-2019-5762;CVE-2019-5763;CVE-2019-5764;CVE-2019-5765;CVE-2019-5766;CVE-2019-5767;CVE-2019-5768;CVE-2019-5769;CVE-2019-5770;CVE-2019-5771;CVE-2019-5772;CVE-2019-5773;CVE-2019-5774;CVE-2019-5775;CVE-2019-5776;CVE-2019-5777;CVE-2019-5778;CVE-2019-5779;CVE-2019-5780;CVE-2019-5781;CVE-2019-5782,445,10,100.111.222.3,TRUE
121514,Google Chrome < 72.0.3626.81 Multiple Vulnerabilities,Critical,2/28/2019 6:24,2/28/2019 6:24,1/29/2019 9:00,CVE-2019-5754;CVE-2019-5755;CVE-2019-5756;CVE-2019-5757;CVE-2019-5758;CVE-2019-5759;CVE-2019-5760;CVE-2019-5761;CVE-2019-5762;CVE-2019-5763;CVE-2019-5764;CVE-2019-5765;CVE-2019-5766;CVE-2019-5767;CVE-2019-5768;CVE-2019-5769;CVE-2019-5770;CVE-2019-5771;CVE-2019-5772;CVE-2019-5773;CVE-2019-5774;CVE-2019-5775;CVE-2019-5776;CVE-2019-5777;CVE-2019-5778;CVE-2019-5779;CVE-2019-5780;CVE-2019-5781;CVE-2019-5782,445,10,100.111.222.3,TRUE

Desired Output (Take notice on last column showing boolean value for whether a match was found or not)

122111,RHEL 7 : docker (RHSA-2019:0304),High,3/7/2019 8:40,4/1/2019 6:52,2/11/2019 9:00,CVE-2019-5736,0,9.3,100.111.222.1,FALSE
121514,Google Chrome < 72.0.3626.81 Multiple Vulnerabilities,Critical,2/28/2019 6:24,2/28/2019 6:24,1/29/2019 9:00,CVE-2019-5754;CVE-2019-5755;CVE-2019-5756;CVE-2019-5757;CVE-2019-5758;CVE-2019-5759;CVE-2019-5760;CVE-2019-5761;CVE-2019-5762;CVE-2019-5763;CVE-2019-5764;CVE-2019-5765;CVE-2019-5766;CVE-2019-5767;CVE-2019-5768;CVE-2019-5769;CVE-2019-5770;CVE-2019-5771;CVE-2019-5772;CVE-2019-5773;CVE-2019-5774;CVE-2019-5775;CVE-2019-5776;CVE-2019-5777;CVE-2019-5778;CVE-2019-5779;CVE-2019-5780;CVE-2019-5781;CVE-2019-5782,445,10,100.111.222.2,TRUE
121514,Google Chrome < 72.0.3626.81 Multiple Vulnerabilities,Critical,2/28/2019 6:24,2/28/2019 6:24,1/29/2019 9:00,CVE-2019-5754;CVE-2019-5755;CVE-2019-5756;CVE-2019-5757;CVE-2019-5758;CVE-2019-5759;CVE-2019-5760;CVE-2019-5761;CVE-2019-5762;CVE-2019-5763;CVE-2019-5764;CVE-2019-5765;CVE-2019-5766;CVE-2019-5767;CVE-2019-5768;CVE-2019-5769;CVE-2019-5770;CVE-2019-5771;CVE-2019-5772;CVE-2019-5773;CVE-2019-5774;CVE-2019-5775;CVE-2019-5776;CVE-2019-5777;CVE-2019-5778;CVE-2019-5779;CVE-2019-5780;CVE-2019-5781;CVE-2019-5782,445,10,100.111.222.3,TRUE

Solution

  • If I understand correctly, it would be easier to process FILE2.csv before FILE1.csv so you would have the necessary information to print the TRUE/FALSE boolean when you encounter each entry from FILE1.csv. So, modifying your script slightly, this just looks up each value from the split in a stored array of values from FILE2.csv

    awk -F, '
    NR == FNR {
        a[$1] = 1
        next
    }
    
    {
        n = split($7, x, ";")
        for (i = 1; i < n; i++)
            if (x[i] in a) {
                print $0 ",TRUE"
                next
            }
        print $0 ",FALSE"
    }' FILE2.csv FILE1.csv