Topher Fangio
Topher Fangio

Reputation: 20667

Indenting Bash Script Output

I am attempting to write a bash script and I am having difficulty making the output look neat and organized. I could fall back on just using newlines, but I would much rather have output that was easy to read. For instance, when I run git clone ..., I want to first echo "Cloning repository" and then have the output of git indented. Example output:

Cloning repository...
    Initialized empty Git repository in /root/client_scripts/jojo/.git/
    remote: Counting objects: 130, done.
    remote: Compressing objects: 100% (121/121), done.
    remote: Total 130 (delta 13), reused 113 (delta 6)
    Receiving objects: 100% (130/130), 176.07 KiB, done.
    Resolving deltas: 100% (13/13), done.

Currently, it's all compressed with no indentation. Does anyone know how to do this? I attempted with sed and awk but it didn't seem to show any more output than just Initialized empty Git repository in /root/client_scripts/jojo/.git/. I would greatly appreciate any comments.

Upvotes: 21

Views: 12170

Answers (5)

Joey
Joey

Reputation: 354694

Pipe through

sed "s/^/    /g"

This will replace the (zero-width) anchor for line start by four spaces, effectively adding four spaces at the start of the line.

(The g does this globally; without it, it will only do it once, which would do the first line.)

Upvotes: 48

CB Bailey
CB Bailey

Reputation: 792517

The problem with piping the output of git through any command is that git will detect that the output is not a terminal so it won't output messages which are progress messages because (typically) it is not useful to pipe a whole lot of terminal characters and progress updates to something that isn't a terminal.

To get the progress messages anyway you need to provide the --verbose option to git clone. The progress messages appear on stderr so you are likely to need a pipe something like 2>&1 | ....

Be aware the the progress messages won't appear line by line, but you'll get a lot of terminal escape codes which are designed to clear the same line. Trying to indent this output by piping through a line based tool like sed is likely to prove difficult, if not impossible. For a program that can handles input unbuffered, it should be fairly possible to look for a ^M in the output and add some spaces (or a tab) immediately aftwards, flushing as often as each batch of data is received.

Upvotes: 7

Mark Rushakoff
Mark Rushakoff

Reputation: 258358

Since the awk solution wasn't posted yet:

$ echo -en "hello\nworld\n"
hello
world
$ echo -en "hello\nworld\n" | awk '{print "    "$0}'
    hello
    world

Upvotes: 5

Juliano
Juliano

Reputation: 41407

A different solution that doesn't require sed:

command | (while read; do echo "    $REPLY"; done)

Upvotes: 9

hlovdal
hlovdal

Reputation: 28228

You can filter the output from the command you want to indent through sed.

/tmp/test>cat script
#!/bin/sh

echo "Running ls -l"
ls -l 2>&1 | sed 's/^/\t/'

/tmp/test>sh script
Running ls -l
        total 4
        -rw-rw-r-- 1 hlovdal hlovdal 55 2009-11-03 23:36 script
/tmp/test>

The sed command will replace the beginning of the line (before the first character) with a tabulator, i.e. insert a tabulator at the very beginning of the line.

Updated to also indent stderr.

Upvotes: 6

Related Questions