text: user1421: I have a fasta file like this:
  >Id1
  ATCCTT
  >Id2
  ATTTTCCC
  >Id3
  TTTCCCCAAAA
  >Id4
  CCCTTTAAA
  
  I want to delete sequences that have the following IDs.
  Id2
  Id3
  
  The IDs are in a .txt file, and the text file will be used to match and delete those sequences. 
  My output should be a fasta file like this
  >Id1
  ATCCTT
  >Id4
  CCCTTTAAA
  
  But I want it with awk and/or sed and/or bash (no python or perl).
  How can I do it?
  
  user29: 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.
  
  user4472: Shortest way...
  awk '!/Id2|Id3/' RS=">" ORS=">" fasta.fa
  
  != Not match the pattern
  Note: Sequence doesn't need to be in a single line!
  
  user-1: Presume grep is OK if sed, awk are. The -A(n) and -B(n) flags give (n) lines post match. Presuming all your fasta sequence will be one line is a bit dangerous, but it works for your example. First get those IDs to be removed (in rmid.txt), then inverse grep against the initial fasta.
  grep -A1 -f rmid.txt fasta.fa > rmfile.fa
  grep -v -f rmfile.fa fasta.fa
  
  The real answer is to use a script that defines a delimiter other than newline "\n", then parse for IDs, so better to use one of the languages you don't want to use... 
  
  user298: Using the FastaToTbl and TblToFasta scripts I have posted before, you can do:
  FastaToTbl file.fa | grep -vwf ids.txt | TblToFasta > file.2.fa
  
  
  user776: If you want to learn how to do things with command-line tools, you can linearize the FASTA with awk, pipe to grep to filter for items of interest named in patterns.txt, then pipe to tr to delinearize:
  $ awk '{ if ((NR>1)&&($0~/^>/)) { printf("\n%s", $0); } else if (NR==1) { printf("%s", $0); } else { printf("\t%s", $0); } }' in.fa | grep -Ff patterns.txt - | tr "\t" "\n" > out.fa
  
  This will work on multiline FASTA.
  
  user37: Suppose you keep sequence names in ids.txt and sequences in seq.fa:
  awk 'BEGIN{while((getline<"ids.txt")>0)l[">"$1]=1}/^>/{f=!l[$1]}f' seq.fa
  
  
  user57: Just today I wrote a script to do exactly this using Biopython. I also add a warning If any the headers I wanted to filter was not present in the original fasta. So the python script filter_fasta_by_list_of_headers.py is :
  #!/usr/bin/env python3
  
  from Bio import SeqIO
  import sys
  
  ffile = SeqIO.parse(sys.argv[1], "fasta")
  header_set = set(line.strip() for line in open(sys.argv[2]))
  
  for seq_record in ffile:
      try:
          header_set.remove(seq_record.name)
      except KeyError:
          print(seq_record.format("fasta"))
          continue
  if len(header_set) != 0:
      print(len(header_set),'of the headers from list were not identified in the input fasta file.', file=sys.stderr)
  
  and usage :
  filter_fasta_by_list_of_headers.py input.fasta list_of_scf_to_filter > filtered.fasta
  
  P.S. it's quite easy to turn over the script to extract the sequences from the list (just the print line would have to move after line header_set.remove(seq_record.name)
  
original_text: 1421: <p>I have a fasta file like this:</p>
  
  <pre><code>&gt;Id1
  ATCCTT
  &gt;Id2
  ATTTTCCC
  &gt;Id3
  TTTCCCCAAAA
  &gt;Id4
  CCCTTTAAA
  </code></pre>
  
  <p>I want to delete sequences that have the following IDs.</p>
  
  <pre><code>Id2
  Id3
  </code></pre>
  
  <p>The IDs are in a .txt file, and the text file will be used to match and delete those sequences. </p>
  
  <p>My output should be a <code>fasta</code> file like this</p>
  
  <pre><code>&gt;Id1
  ATCCTT
  &gt;Id4
  CCCTTTAAA
  </code></pre>
  
  <p>But I want it with <code>awk</code> and/or <code>sed</code> and/or <code>bash</code> (no python or perl).<br>
  How can I do it?</p>
   29: <p>This is what <strong><code>samtools faidx</code></strong> is intended for.</p>
  <p>It needs to be called twice.</p>
  <ol>
  <li><p>First, to create a FASTA index (<code>*.fai</code> file):</p>
  <pre class="lang-sh prettyprint-override"><code>samtools faidx input.fasta
  </code></pre>
  </li>
  <li><p>Secondly, to filter the FASTA file with the help of the index:</p>
  <pre class="lang-sh prettyprint-override"><code>samtools faidx -o output.fasta input.fasta ids…
  </code></pre>
  </li>
  </ol>
  <p><code>ids…</code> are the IDs to retain, as individual arguments separated by space. If you’ve got a file <code>blocklist.txt</code> with IDs you want to <em>discard</em> (one per line), you first need to invert this, after having created the index (using Bash syntax):<sup>1</sup></p>
  <pre class="lang-bash prettyprint-override"><code>remove_ids=($(awk '{print $1}' input.fasta.fai | grep -v -f blocklist.txt))
  </code></pre>
  <p>… and then we can invoke the command as</p>
  <pre><code>samtools faidx -o output.fasta input.fasta &quot;${remove_ids[@]}&quot;
  </code></pre>
  <p>What’s nice about <code>samtools faidx</code> is that it also works with <a href="http://www.htslib.org/doc/bgzip.html" rel="nofollow noreferrer">BGZF-compressed FASTA</a> data — i.e. <code>fa.gz</code> files (but <em>only</em> if they were compressed using <code>bgzip</code>, 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 <code>bgzip</code>:</p>
  <pre><code>
  samtools faidx input.fasta.gz &quot;${remove_ids[@]}&quot; | bgzip -c &gt;output.fasta.gz
  </code></pre>
  <hr />
  <p><sup>1</sup> <sub><strong>Careful</strong>, this syntax is <em>generally unsafe</em> for reading a command output into a variable; we can use it here only because we assume that we want to generate a <em>space</em>-separated list of identifiers; the generally safe way is <a href="https://unix.stackexchange.com/a/485262/3651">a lot more convoluted</a>.</sub></p>
   4472: <p>Shortest way...</p>
  <pre><code>awk '!/Id2|Id3/' RS=&quot;&gt;&quot; ORS=&quot;&gt;&quot; fasta.fa
  </code></pre>
  <p><code>!</code>= Not match the pattern
  <code>Note:</code> Sequence doesn't need to be in a single line!</p>
   -1: <p>Presume grep is OK if sed, awk are. The -A(n) and -B(n) flags give (n) lines post match. Presuming all your fasta sequence will be one line is a bit dangerous, but it works for your example. First get those IDs to be removed (in rmid.txt), then inverse grep against the initial fasta.</p>
  
  <pre><code>grep -A1 -f rmid.txt fasta.fa &gt; rmfile.fa
  grep -v -f rmfile.fa fasta.fa
  </code></pre>
  
  <p>The real answer is to use a script that defines a delimiter other than newline "\n", then parse for IDs, so better to use one of the languages you don't want to use... </p>
   298: <p>Using the <code>FastaToTbl</code> and <code>TblToFasta</code> scripts I have <a href="https://bioinformatics.stackexchange.com/a/2651/298">posted before</a>, you can do:</p>
  
  <pre class="lang-none prettyprint-override"><code>FastaToTbl file.fa | grep -vwf ids.txt | TblToFasta &gt; file.2.fa
  </code></pre>
   776: <p>If you want to learn how to do things with command-line tools, you can linearize the FASTA with <code>awk</code>, pipe to <code>grep</code> to filter for items of interest named in <code>patterns.txt</code>, then pipe to <code>tr</code> to delinearize:</p>
  
  <pre><code>$ awk '{ if ((NR&gt;1)&amp;&amp;($0~/^&gt;/)) { printf("\n%s", $0); } else if (NR==1) { printf("%s", $0); } else { printf("\t%s", $0); } }' in.fa | grep -Ff patterns.txt - | tr "\t" "\n" &gt; out.fa
  </code></pre>
  
  <p>This will work on multiline FASTA.</p>
   37: <p>Suppose you keep sequence names in <code>ids.txt</code> and sequences in <code>seq.fa</code>:</p>
  
  <pre><code>awk 'BEGIN{while((getline&lt;"ids.txt")&gt;0)l["&gt;"$1]=1}/^&gt;/{f=!l[$1]}f' seq.fa
  </code></pre>
   57: <p>Just today I wrote a script to do exactly this using <code>Biopython</code>. I also add a warning If any the headers I wanted to filter was not present in the original fasta. So the python script <code>filter_fasta_by_list_of_headers.py</code> is :</p>
  
  <pre><code>#!/usr/bin/env python3
  
  from Bio import SeqIO
  import sys
  
  ffile = SeqIO.parse(sys.argv[1], "fasta")
  header_set = set(line.strip() for line in open(sys.argv[2]))
  
  for seq_record in ffile:
      try:
          header_set.remove(seq_record.name)
      except KeyError:
          print(seq_record.format("fasta"))
          continue
  if len(header_set) != 0:
      print(len(header_set),'of the headers from list were not identified in the input fasta file.', file=sys.stderr)
  </code></pre>
  
  <p>and usage :</p>
  
  <pre><code>filter_fasta_by_list_of_headers.py input.fasta list_of_scf_to_filter &gt; filtered.fasta
  </code></pre>
  
  <p>P.S. it's quite easy to turn over the script to extract the sequences from the list (just the print line would have to move after line <code>header_set.remove(seq_record.name</code>)</p>
  