How to insert tabs before output lines from a executed command

You could do something like this - with file descriptors:

  1. save the current output descriptor so we can restore it later

    exec 3>&1
    
  2. redirect the output stream to a process substitution that inserts the tab - for example

    exec 1> >(paste /dev/null -)
    

From this point, any process that writes to standard output will have that output 'filtered' through the paste command to insert tabs at the start.

  1. When you're done, you can resume normal behavior by restoring the saved file descriptor and closing the temporary one

    exec 1>&3 3>&-
    

I understand this answer is not optimal for you, but you could make a Bash function with the simple name like _ (or anything else that is not used yet) which runs the command it gets as arguments and indents all of its output with a tab.

An example:

$ _ lsb_release -a
    No LSB modules are available.
    Distributor ID: Ubuntu
    Description:    Ubuntu 16.04 LTS
    Release:    16.04
    Codename:   xenial

More complex shell constructs would be possible too, but need to be given as quoted argument or with special characters escaped to prevent evaluation before it was passed to the function.

$ _ 'for x in {1..3} ; do echo $x ; done'
    1
    2
    3

$ _ for x in \{1..3\} \; do echo \$x \; done
    1
    2
    3

The code for this function would only be this:

_(){ eval "$@" |& sed "s/^/\t/" ; return "$PIPESTATUS" ;}

As a side effect, this would merge STDERR into STDOUT in order to indent both, but on the other hand it also preserves the exit status of the given command.

You can append this line above to your ~/.bashrc file so that it will be available in all Bash sessions of your user.


The previous version of this answer suggested the function below, but that would not indent STDERR streams and also suppress return/exit codes in case the given command fails. Besides, it would have broken commands with quotes or significant whitespace due to the bad $* variable expansion instead of "$@", and probably there were even more problems...

_(){ sed "s/^/\t/" <($*); }

With echo specifically, you can have it interpret backslash escapes like \t (a tab stop) with the -e switch:

echo -e "\tHello World"

But it would hardly be feasible (or probably possible) to modify the output the of every command that way. If ease of read is your goal, you might want to look into customizing the look (e. g. the coloring) of your command prompt, like shown here:

You can customize your prompt by changing the content of the environment variable PS1. You can see a little example of how to do that in the blog post the above screenshot is from. How to use those so called ANSI escape sequences in detail, how to use tools that are more comfortable, how to have the changes applied by default in new terminals etc. are beyond the scope of this answer. But if you decide to use that technique, there are a lot of tutorials and further information around the web.