1

I have a code that extracts from the following table (testtam.txt)

gene1   1   3   5   9           
gene2   0   0   4   4           
gene3   1   0   1   2           
gene4   5   5   0   10          
gene5   2   0   0   2   

the rows where only one of fields 2, 3 or 4 have a value that is not 0 and saves them into a separate file (match-file):

awk '{
    if (    ($2 == $5 && $3 == 0 && $4 == 0) || \
        ($2 == 0 && $3 == $5 && $4 == 0) || \
        ($2 == 0 && $3 == 0 && $4 == $5) ) {
        print $0 > "match-file"
}   else if ($2 + $3 + $4 == $5) {
        print $0 > "nomatch-file"
     }    
}' testtam.txt

The problem is that is does not work with .csv files, e.g. if I have that kind of .csv table

gene1,1,3,5,9           
gene2,0,0,4,4           
gene3,1,0,1,2           
gene4,5,5,0,10          
gene5,2,0,0,2

awk recognizes it as a one single column.

How can I make my code read columns from .csv?

  • Your code doesn't do what you say it does. Are you really only looking for lines with only one non-0 value or do you also require $3 to be the same as $5 or $4 to be the same as $5? – terdon Dec 9 '19 at 19:15
  • Thank you, I only need rows that have only one value in it, for example I need to have gene2 and gene5 in one file and gene1,gene3 and gene4 in another file.. – Mark Dec 9 '19 at 20:07
  • Sorry I meant only one non-0 value, yes. But that value must correspond to the one in the very last column - that is actually the sum of all values in all previous columns (like in my example). That is why I thought it could be a good idea to separate these rows by comparing a single non-zero value with the last one so if they do match - this is the row I need to separate in another file.. – Mark Dec 9 '19 at 20:28
  • Ah, I see. In that case, see updated answer for a shorter version. – terdon Dec 9 '19 at 21:14
1

You just need to use a different field-delimiter. That's what awk's -F option dos:

awk -F',' '{
    if (    ($2 == $5 && $3 == 0 && $4 == 0) || \
        ($2 == 0 && $3 == $5 && $4 == 0) || \
        ($2 == 0 && $3 == 0 && $4 == $5) ) {
        print $0 > "match-file"
}   else if ($2 + $3 + $4 == $5) {
        print $0 > "nomatch-file"
     }    
}' 

or, if what you want is to match those lines where at least two of the fields from the 2nd till the last have values that are not 0, you could just do:

awk -F, '{ 
            c=0; 
            for(i=2;i<=NF-1;i++){ 
                c+= $i!=0
            } 
            print > ((c > 1) ? 
                "match-file" : 
                "nomatch-file")
          }' file
  • Thank you so much. That is exactly what I was looking for. – Mark Dec 9 '19 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.