title: Piping the same output through one or several grep commands on condition
body: <p>I am currently writing a bash script to modify the output of my LaTeX compilations to have only what I find relevant printing on the console. As I would like this script to be extremely thorough, I set up different options to toggle different output filters at the same time depending of the nature of the informations given through the compilation (Fatal error, warning, over/underfull h/vbox...).</p>
  <p>For those who may not know, we often need to perform several compilations in a row to have a full LaTeX document with correct labels, page numbering, index, table of contents... + other commands like <code>bibtex</code> or <code>makeglossaries</code> for bibliography and, well, glossaries. I therefore have a loop that execute everything and stops if there is a fatal error encountered, but <strong>should</strong> continue if it is only a minor warning.</p>
  <p>My main command line is piping the <code>pdflatex</code> output through a reversed <code>grep</code> that finds errors line (starting by <code>!</code>). Like this, the script stops only if <code>grep</code> found a fatal error.</p>
  <pre><code>: | pdflatex --halt-on-error $@ | { ! grep --color=auto '^!.*' -A200; }
  </code></pre>
  <p>But when I activate any other filters (eg. <code>'*.full.*'</code> for over/underfull lines), I need to be able to continue compiling to be able to identify it there is a major necessity to correct it (hey, sometimes, underfull lines are just not <em>that</em> ugly...).</p>
  <p>That means my <code>grep</code> command cannot be inverted as in the first line, and I cannot (or don't know how to) use the same <code>grep</code> with a different regex. notice that if if using a different <code>grep</code>, it should also be read from the <code>pdflatex</code> output and I cannot pipe it directly following the above snippet.</p>
  <p>To sum up, it should roughly look like this :</p>
  <pre><code>   pdflatex --&gt; grep for fatal errors --&gt; if more filters, grep for those filters
     --&gt; pass to next step
  </code></pre>
  <p>I came up with several attempts that did not work properly :</p>
  <p>This one works only if I want to compile WITH the warnings. Looking only for errors does not work.</p>
  <pre><code>latex_compilation() {
  : | pdflatex --halt-on-error $@ | tee &gt;({ ! grep --color=auto '^!.*' -A200; }) &gt;({ grep --color=auto &quot;$warnings_filter&quot; -A5 };) &gt;/dev/null
  }
  
  
  latex_compilation() {
  : | pdflatex --halt-on-error $@ | tee &gt;({ ! grep --color=auto '^!.*' -A200; }) &gt;/dev/null | ({ grep --color=auto &quot;$warnings_filter&quot; -A5 };)
  }
  </code></pre>
  <p>or even desperately</p>
  <pre><code>latex_compilation() {
  : | pdflatex --halt-on-error $@ |
  if [[ &quot;$warnings_on&quot; = true ]]; then
      { grep --color=auto &quot;$warnings_filter&quot; -A5 };
  fi
  { ! grep --color=auto '^!.*' -A200; }
  }
  </code></pre>
  <p>This one would work but uses 2 compilation processes for each step (you could easily go up to 7/8 compilations steps for a big and complex document). It should be avoided if possible.</p>
  <pre><code>latex_compilation() {
  if [[ &quot;$warnings_on&quot; = true ]]; then
      : | pdflatex --halt-on-error $@ | \
      { grep --color=auto &quot;$warnings_filter&quot; -A5 };
  fi
  : | pdflatex --halt-on-error $@ | \
  { ! grep --color=auto '^!.*' -A200; }
  }
  </code></pre>
  <p>I spent hours looking for solutions online, but didn't find any yet.
  I really hope this is clear enough because it is a mess to sum up, moreover writing it. You can find the relavant code <a href="https://pastebin.com/xNbBi7ze" rel="nofollow noreferrer">here</a> if needed for clarity.</p>