How to not print a line if it and the following line starts with the same pattern?

Viewed 143

I have a file.fa:

>ABC
TGTGTGT
AGAGAGA
TGTAGTA
>BDC
>DTR
>EDF
AGAGGTG
AGTGACA
CAGTGAC

I want to keep the lines without ">", and lines with ">" only if the immediate following line does not have ">":

>ABC
TGTGTGT
AGAGAGA
TGTAGTA
>EDF
AGAGGTG
AGTGACA
CAGTGAC

Looking at the answer for this post, I see that awk '/^>/{x=$0} !/^>/{if(x){print x;x=0;}}' file.fa prints out the header lines (with '>') that I want:

>ABC
>EDF

but how do I also get the lines of text without '>'?

6 Answers

Using sed:

$  sed '/^>/ { N; /\n>/ D; }' input.txt
>ABC
TGTGTGT
AGAGAGA
TGTAGTA
>EDF
AGAGGTG
AGTGACA
CAGTGAC

If a line starts with >, read the next line and append it to the pattern space. If it also starts with >, delete the first line of the pattern space and repeat with the second line just read as the new input line to look at. Print everything else.

You may use:

awk '!/^>/ {if (prev != "") print prev; print; prev=""}
/^>/ {prev = $0}' file

>ABC
TGTGTGT
AGAGAGA
TGTAGTA
>EDF
AGAGGTG
AGTGACA
CAGTGAC
$ awk '!/>/{print p $0; p=""; next} {p=$0 ORS}' file
>ABC
TGTGTGT
AGAGAGA
TGTAGTA
>EDF
AGAGGTG
AGTGACA
CAGTGAC

The above assumes you don't have a > line as the last line of the input.

With your shown samples only, please try following awk code. Simple explanation would be, setting RS(record separator) as > and field separator as new line. If NF is greater than 2 then print that line with > and it values.

awk -v RS='>' -v FS='\n' 'NF>2{sub(/\n$/,"");print ">" $0}' Input_file

We always have perl:

perl -0777 -ne 'print $1 while(/^(>.*\R^[^>][\s\S]*?)(?=^>|\z)/gm)' file
>ABC
TGTGTGT
AGAGAGA
TGTAGTA
>EDF
AGAGGTG
AGTGACA
CAGTGAC

In awk you could do:

awk -F"^>" 'NF>1{p=$0 ORS; next}
{printf "%s%s", p, $0 ORS; p=""}' file

This might work for you (GNU sed):

sed 'N;/^>.*\n>/!P;D' file
Related