title: Format multiline command output in bash using printf
body: <p>My Bash script uses <code>printf</code> to print output of some other commands with formatting applied, in the following manner (note the two leading spaces):</p>
  
  <pre><code>printf "  %-16s %s\n" "foo:" "$(bar)"
  </code></pre>
  
  <p>The two leading spaces are there, because the first line in the file is a comment, and I like to keep things nicely aligned:</p>
  
  <pre><code># foo
    foo:            bar
    foo:            bar
    ...
  </code></pre>
  
  <p>This works perfectly fine for commands with one-line output. However, when the output is multiline, the output looses the formatting of the subsequent lines.</p>
  
  <p>For example:</p>
  
  <pre><code>printf "  %-16s %s\n" "Contents:" "$(ls -a)"
  </code></pre>
  
  <p>Results in something like this:</p>
  
  <pre><code>  Contents:       .
  ..
  foo
  bar
  </code></pre>
  
  <p>Instead, what I am trying to achieve is multiline output, with each line formatted (in columns, if you like), which would look like this (note the lack of "header" in the subsequent lines):</p>
  
  <pre><code>  Contents:       .
                    ..
                    foo
                    bar
  </code></pre>
  
  <p>My understanding so far is that <code>printf</code> with two arguments (the first one being a string, and the other one the result of the given command) treats the second argument as a single string, which can include newline characters within. Therefore, the output is actually correctly formatted, according to what I asked <code>printf</code> to do, but it is not what I am looking for.</p>
  
  <p>I am aware about some of the pitfalls related to parsing the output of commands like <code>ls</code>, which exhausts my current possibilities of solving this problem. Also, it is possible that <code>printf</code> is not the best facility to do this.</p>
  
  <p>I am considering substituting multiline string into comma-separated list, if no solution to this problem is possible, but this would be a last resort.</p>
  
  <p>What would be the best method to achieve the formatting I need?</p>
  
  <p>Thanks for your help.</p>