Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have input like the following:

>gi|481443199|gb|MH447771.1|
49      0       0       0       1
50      0       0       1       0
>gi|987078004|gb|RTYJ01067061.1|
412     0       0       1       0
413     1       0       0       0
>gi|557075006|gb|ERTJ01078061.1|
41     0       0       1       0
41     1       0       0       0
>gi|787073002|gb|WERJ01045061.1|
612     0       0       1       0
613     1       0       0       0
>gi|887079001|gb|WERJ01045061.1|
715     0       0       1       0
716     1       0       0       0

I want to print some lines, but skip every other line that starts with > (along with all the lines after it, until the subsequent >). For the example input above, the output would be:

>gi|481443199|gb|MH447771.1|
49      0       0       0       1
50      0       0       1       0
>gi|557075006|gb|ERTJ01078061.1|
41     0       0       1       0
41     1       0       0       0
>gi|887079001|gb|WERJ01045061.1|
715     0       0       1       0
716     1       0       0       0

How can I do that?

share|improve this question

closed as too localized by jw013, manatwork, Renan, Shawn J. Goff, warl0ck Oct 12 '12 at 23:48

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

4 Answers 4

up vote 8 down vote accepted

To skip every other > ... block:

 awk '/^>/ { p = !p } p' input.txt

p is a print flag - p means print when p is true, as the default action is print when none is provided. In awk, variables start out empty, which evaluates to false in Boolean contexts. Every time a > ... line is reached, toggle the p flag.

To print every nth block delimited by > ... lines:

awk -v n=200 '/^>/ { if (skip == 0) skip = n - 1; else --skip; } skip == n - 1' input.txt

It's similar logic, except since n is not 2 we have to use a counter instead of a Boolean flag. Here, skip counts how many more > ... lines to skip before we start printing again. I'm using skip == n - 1 as the print flag as a bit of a short cut.

share|improve this answer
    
sorry, as I am new to awk, Could you please explain me. In my question I asked to skip every 2nd ">", what I can do If want to skip every 200 occuring ">" –  jack Oct 12 '12 at 16:03
    
+1 for nice and simple in your first solution. The second command does not work though, it prints the 1st line and then each n+1th line after that. I.e. for n=4, it will print the 1st,6th,11th,16th etc instead of 1st,5th,9th,13th etc. –  terdon Oct 12 '12 at 16:28
    
@terdon You are right, I had an off-by-1 bug. I feel slightly embarrassed lol. :P –  jw013 Oct 12 '12 at 16:33
    
No worries, happens to the best of us :) –  terdon Oct 12 '12 at 16:34

For a more general solution, you can try this:

awk 'k%10==0{print} /^>/ {k++}' input.txt

This increments the variable k every time a line starts with > and prints the lines if k modulo 10 is 0. So, if you want to print every 2nd line, change k%10==0 to k%2==0, for every 200th line change it to k%200==0 etc.

WARNING: In this version, the first line will ALWAYS be printed.

share|improve this answer
$ awk '/^>/{f=f?0:1;}f' file

Just switching a flag variable on and off on encoutering a line beginning with '^'. When it is on, print lines, else don't.

share|improve this answer

For awk you can do:

awk 'BEGIN{pr=true}/^>/{pr=!pr}{if (pr) {print}}'

This sets a flag (pr) for when to print, that is toggled every appearance of your token.

share|improve this answer

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