1

I have an input that is in a multi-fasta format. Essentially:

>header1
AAAAAATTTTCCCCGGGG
AAAATGTGTGTCTCTCTC
ATAGGATGAGT
>header2
GGGGTGTGTGATGTAGTA
AAAATGTGTGTCTCTCTC
ATAGGATGAGT
....
>header720
GGGGTGCTCGCTCTGTGA
AAAATGAGTCATCATTGT
ATAGGATGAGT

I am interested in recovering entry #28 in this format:

>header28
GGGGTGCTCGCTCTGTGA
AAAATGAGTCATCATTGT
ATAGGATGAGT

My initial attempt was to use sed. However, sed -n '/header28/,/>/p' ('get everything from the line matching the pattern to the next symbol >') leads to:

>header28
GGGGTGCTCGCTCTGTGA
AAAATGAGTCATCATTGT
ATAGGATGAGT
>header29

Meanwhile, sed -n '/header28/,/[^>]*/p' ('get everything from the line matching the pattern to, but not including, the symbol >') results in a shorter sequence than I need because it gets stuck on the newlines as follows:

>header28
GGGGTGCTCGCTCTGTGA

In addition, none of these options deal with the possibility that the entry is the last in the list (and therefore not followed by another >). This is unlikely, and I could live with it, but code which could deal with this too would be great.

Help would be much appreciated! Open to other options than sed, but I thought I would aim for something simple.

5 Answers 5

1

Most likely, this has been asked before... but anyway, just delete the range end if present:

sed  '/>header28/,/>/!d;/>/{
     />header28/!d
     }' infile
1

Using any awk:

$ awk '/^>/{f=(/>header28$/)} f' file
>header28
GGGGTGCTCGCTCTGTGA
AAAATGAGTCATCATTGT
ATAGGATGAGT

or more efficiently you could exit after that block is printed instead of continuing to read the rest of the input with:

$ awk '/^>/{if (f) exit; f=(/>header28$/)} f' file
>header28
GGGGTGCTCGCTCTGTGA
AAAATGAGTCATCATTGT
ATAGGATGAGT
0

With awk:

awk -v hdrId='header28' '
  /^>header/ && buf{ printf("%s", buf); exit }
  $0 ~ "^>" hdrId "$" || buf{ buf=buf $0 ORS }' infile
0

Use sed.

Use buffer to store all lines after >header28
starting with letter and stop
checking if it doesn't match (next >headerXX).

Then print the buffer

sed -n '/>header28/{h;:X;n;/^[:alpha]]/{H;bX};g;p;}' file.txt
0

I would use the FastaToTbl and TblToFasta scripts (see here for the scripts) which I have mentioned in other answers, and just do:

$ FastaToTbl file.fa | grep -w header28 | TblToFasta
>header28 
GGGGTGCTCGCTCTGTGAAAAATGAGTCATCATTGTATAGGATGAGT

Note that this will present the sequence split into lines of 60 characters, which used to be the norm 20 years ago when these scripts were written. Since this is fasta, I am assuming there is no need to keep the original line folding. Please let me know if that's not the case.

You must log in to answer this question.

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