1

I have a file that looks like this:

chr1    3000823 3000829 1  
chr1    3001003 3001009 1  
chr1    3001014 3001020 1  
chr1    3001273 3001279 2  
chr1    3001625 3001631 3  
chr1    3003222 3003228 4  
chr1    3003335 3003341 4  
chr1    3003375 3003381 4  
chr1    3003578 3003584 4  
chr1    3003636 3003642 4  
chr1    3003717 3003723 4  
chr1    3003881 3003887 4  
chr1    3003894 3003900 4  
chr1    3004526 3004532 5  
chr1    3005994 3006000 6  
chr1    3006183 3006189 6  
chr1    3006412 3006418 7  
chr1    3006778 3006784 8  
chr1    3006877 3006883 8  
chr1    3007166 3007172 9  
chr1    3007426 3007432 10      
chr1    3007528 3007534 10  
chr1    3007576 3007582 10  

And I would like to take only the rows that contain a specific number of times any number in the 4th column.

Lets say I would like to take rows that have 3 times the same number in the 4th column so the output would be:

chr1    3000823 3000829 1  
chr1    3001003 3001009 1  
chr1    3001014 3001020 1  
chr1    3007426 3007432 10  
chr1    3007528 3007534 10  
chr1    3007576 3007582 10  

..this is because these rows have the number 1 and 10 that is present 3 times in the 4th column

Any idea would be very appreciated. Thanks!

3

A solution with awk:

awk 'FNR==NR{c[$4]++;next;} c[$4]==3' file.dat file.dat

Output:

chr1    3000823 3000829 1  
chr1    3001003 3001009 1  
chr1    3001014 3001020 1  
chr1    3007426 3007432 10      
chr1    3007528 3007534 10  
chr1    3007576 3007582 10

Explanation:

  • FNR==NR: This test is true when the number of records is equal to the number of records in the file. This is only true for the first file, for the second file NR will be equal to the number of lines of file1 + FNR.
  • c[$4]++: Increment an array element index by $4. I use this as a counter.
  • next: Skip to the next record without doing anything else.
  • c[$4]==3: This only happens on records of the second file. If this test succed the line will be printed, since print is the default action in awk.

This code has the disadvantage to read the file twice, but in my opinion it's a clean and easy to understand way to do this job.

  • could you please explain the command? It worked fine the script. – fusion.slope Dec 5 '16 at 11:37
1
{
  i = int(count[$4])
  arr[$4,i] = $0
  count[$4]++
} 

END {
  for (i in count) {
    if (count[i]== n) {
      for (j=0; j<n; j++) {
        printf("%s\n", arr[i,j])
      } 
    } 
  }
}

sample run --

awk -v n=3 -f 1.awk 1.dat 
chr1 3007426 3007432 10
chr1 3007528 3007534 10
chr1 3007576 3007582 10 
chr1 3000823 3000829 1
chr1 3001003 3001009 1
chr1 3001014 3001020 1

awk -v n=8 -f 1.awk 1.dat 
chr1 3003222 3003228 4
chr1 3003335 3003341 4
chr1 3003375 3003381 4
chr1 3003578 3003584 4
chr1 3003636 3003642 4
chr1 3003717 3003723 4
chr1 3003881 3003887 4

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.