Compare two numerical ranges in two distincts files with awk

Viewed 48

I have a file1 with 3 columns. Columns 2 and 3 define a numerical range. Data are sorted from the smaller to the bigger value in column 2. Numerical ranges never overlap.

file1 (reference)

S   24     96
S   126    352
S   548    600
S   724    736

I have a second file2 (test) structured similarly.

file2 (test)

S   27     93
S   123    355
S   542    584
S   726    740
S   1014   2540
S   12652  12987

Desired output: print lines of file2 for which ranges overlap (including partially) the ones of file1

output

S   27     93     * partially overlap with L1 of file1
S   123    355    * partially overlap with L2 of file1
S   542    584    * partially overlap with L3 of file1
S   726    740    * partially overlap with L4 of file1

What I tried so far:

  1. I tried to adapt the solution provided by @EdMorton to a similar question: Comparing two columns in two files using awk

    awk 'NR==FNR{a[$2,$3];next} ($2,$3) in a' file1 file2

The main difference between this question and mine is that they were searching for exact same ranges in both files. In my case, numerical ranges can be only partial (down to only one position). With this solution, I searched for changing the expression ($2,$3) in a to compare the ranges of file2 to the ones stored in the array. Without any success.

  1. I tried the approach of not storing numerical ranges in the array but individual numbers (column 2 in a and column 3 in b of file1) and then compare column 2 and 3 of file 2 with the ones stored in the array.

    awk 'NR==FNR {a[$1]=$2; b[$1]=$3; next} ($2 <= a[$1] && $3 >= b[$1]) || ($2 >= a[$1] && $3 <= b[$1]) || ($2 <= a[$1] && $3 <= b[$1] && $3 >= a[$1]) || ($2 >= a[$1] && $2 <= b[$1] && $3 >= b[$1])' file1 file 2

This approach did not properly worked neither.

  1. Finally, I also tried the join command like this (see bellow) expecting that I could perform comparisons in the joined file. Unfortunately it did not work neither.

    join file1 file2 | awk '{if ($5 <= $2 && $6 >= $3 || $5 >= $2 && $6 <= $3 || $5 <= $2 && $5 <= $3 && $6 <=$3 || $5 >= $2 && $5 <= $3 && $6 >= $3) {print $0;}}' -

Thanks if you could help me with my question. Best,

1 Answers
$ cat tst.awk
NR == FNR {
    begs2ends[$2] = $3
    next
}
{
    for (beg in begs2ends) {
        end = begs2ends[beg] + 0
        beg += 0
        if (    ( ($2 >= beg) && ($2 <= end) ) ||
                ( ($3 >= beg) && ($3 <= end) ) ||
                ( ($2 <= beg) && ($3 >= end) )  ) {
            print
            next
        }
    }
}

$ awk -f tst.awk file1 file2
S   27     93
S   123    355
S   542    584
S   726    740
Related