0

I've made several attempts at this but clearly missing something and need help.

I have a large table of thousands of lines of information and I'm trying to classify them into groups based on columns 3, 4 and 6. I've already sorted the lines by these columns and now simply want to do the following:

If column 3=previous lines column 3 && column 4 < previous lines column 5 && column 6 = previous lines column 6; then print the row but ammend the start with the line number of the first occurring match; else print the row but ammend the start with the current line number

This was my awful approach full of faults:

awk -F, 'BEGIN { OFS = FS } {if ($4<prev5 && $3==prev3 && $6==prev6) print Marker,$0;else Marker=NR print NR,$0; prev5=$5; prev3=$3; prev6=$6}'

Example input (comma delimited for simplicity of viewing):

a,b,2,15,50,ABBA    
a,a,2,26,55,ABBA    
b,a,2,80,99,ABA    
c,a,3,20,40,CAN    
a,b,3,51,300.CAN    
a,a,4,1000,2000,ART   
d,c,4,1700,2050,ART    
b,a,4,1800,2051,ART

Example output:

1,a,b,2,15,50,ABBA    
1,a,a,2,26,55,ABBA    
3,b,a,2,80,99,ABA    
4,c,a,3,20,40,CAN    
5,a,b,3,51,300.CAN    
6,a,4,1000,2000,ART   
6,c,4,1700,2050,ART    
6,b,a,4,1800,2051,ART   

I'm just trying to group these lines by the given criteria, so the group identifier does not need to use the line number method I've suggested, not if theres a better way to do it.

I really hope someone can help with this as I'm always keen to improve on the basic code I know, so also, if possible, please provide explanation as well, as I would like to learn from my mistakes!

2
  • 1
    Sorry, yes, it was easier to demonstrate input and output using comma as delimiter, but the actual dataset is TAB delimited. I've adjusted the question accordingly
    – Giles
    Oct 10, 2022 at 17:26
  • Sorry, can you put your technical challenge into more broad terms? Such as "I have two columns of values, HI and LO, and I'm looking for an overlap from row-to-row... ", or some similar mathematical description? The point being if the problem is adequately identified, future U&L users will be able to find it more easily. Thx. Oct 10, 2022 at 21:07

1 Answer 1

2

You can make it considerably more readable by spreading the code across several lines:

awk -F, '
    BEGIN { OFS = FS }

    # Each line
    {
        if($3 == prev[3] && $4 < prev[5] && $6 == prev[6])
        {
            # Capture and use record number of last match
            if(!nrMatched) { nrMatched = NR-1 }
            print nrMatched, $0
        }
        else
        {
            # No match, reset matched flag and just copy record through
            nrMatched = 0
            print NR, $0
        }

        # Save fields from this line for next comparison
        split($0, prev)
    }
' datafile

Output

1,a,b,2,15,50,ABBA
1,a,a,2,26,55,ABBA
3,b,a,2,80,99,ABA
4,c,a,3,20,40,CAN
5,a,b,3,51,300.CAN
6,a,a,4,1000,2000,ART
6,d,c,4,1700,2050,ART
6,b,a,4,1800,2051,ART
0

You must log in to answer this question.

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