Indenting multi-line output in a shell script
LinuxBashShellLinux Problem Overview
I'm trying to change the message of the day (MOTD) on my Ubuntu Amazon EC2 box so that it will display the git status of one of my directories when I SSH in.
The output from all of the default MOTD files have two spaces at the start of each line so it looks nicely indented, but because my git status
output spans several lines, if I do echo -n " "
before it only indents the first line.
Any idea how I can get it to indent every line?
Linux Solutions
Solution 1 - Linux
Pipe it to sed
to insert 2 spaces at the beginning of each line.
git status | sed 's/^/ /'
Solution 2 - Linux
Building on @Barmar's answer, this is a tidier way to do it:
indent() { sed 's/^/ /'; }
git status | indent
other_command | indent
Solution 3 - Linux
Thanks to @Barmar and @Marplesoft for some nice simple solutions - here is another variation that others might like - a function you can tell how many indent levels using pr
:
indent() {
local indentSize=2
local indent=1
if [ -n "$1" ]; then indent=$1; fi
pr -to $(($indent * $indentSize))
}
# Example usage
ls -al | indent
git status | indent 2
Solution 4 - Linux
Here's a function I wrote to also indent stderr:
function indented {
local PIPE_DIRECTORY=$(mktemp -d)
trap "rm -rf '$PIPE_DIRECTORY'" EXIT
mkfifo "$PIPE_DIRECTORY/stdout"
mkfifo "$PIPE_DIRECTORY/stderr"
"$@" >"$PIPE_DIRECTORY/stdout" 2>"$PIPE_DIRECTORY/stderr" &
local CHILD_PID=$!
sed 's/^/ /' "$PIPE_DIRECTORY/stdout" &
sed 's/^/ /' "$PIPE_DIRECTORY/stderr" >&2 &
wait "$CHILD_PID"
rm -rf "$PIPE_DIRECTORY"
}
Use it like:
indented git status
indented ls -al