This is what samtools faidx
is intended for.
It needs to be called twice.
First, to create a FASTA index (*.fai
file):
samtools faidx input.fasta
Secondly, to filter the FASTA file with the help of the index:
samtools faidx -o output.fasta input.fasta ids…
ids…
are the IDs to retain, as individual arguments separated by space. If you’ve got a file blocklist.txt
with IDs you want to discard (one per line), you first need to invert this, after having created the index (using Bash syntax):1
remove_ids=($(awk '{print $1}' input.fasta.fai | grep -v -f blocklist.txt))
… and then we can invoke the command as
samtools faidx -o output.fasta input.fasta "${remove_ids[@]}"
What’s nice about samtools faidx
is that it also works with BGZF-compressed FASTA data — i.e. fa.gz
files (but only if they were compressed using bgzip
, which ships with Samtools, and the index must be generated on the compressed file). However, it will always write FASTA. If you want gzipped FASTA output, you need to manually stream the result into bgzip
:
samtools faidx input.fasta.gz "${remove_ids[@]}" | bgzip -c >output.fasta.gz
1 Careful, this syntax is generally unsafe for reading a command output into a variable; we can use it here only because we assume that we want to generate a space-separated list of identifiers; the generally safe way is a lot more convoluted.