Thursday, May 24, 2012

Some light string manipulation in bash

This post is more for me than you.  I had to do a little bash work this morning and thought I'd keep a record of some of the syntax and concepts that I used in case I have to do more in the future.

There are two files here: a function library and a script that consumes it.  The function library is used to do different kinds of string justification (left justify, right justify and centering).  Kind of like 'echo' on steroids.  This could have easily been done in python, perl or ruby, but I wanted it to stay in bash this time to keep the calling scripts uniform.

Here's the sample file that consumes the library:

#!/bin/bash

. echo_helper

x='Steve is here!'
left_justify "$x" 40 .
right_justify "$x" 40 .
center_justify "$x" 40 .

echo $(pad_string 40 -)

x='Steve was here.'
left_justify "$x" 40 .
right_justify "$x" 40 .
echo $(center_justify "$x" 40 .)

And here's what the output should look like:

Steve is here!..........................
..........................Steve is here!
.............Steve is here!.............
----------------------------------------
Steve was here..........................
.........................Steve was here.
............Steve was here..............

Finally, here's the echo_helper library code:



#!/bin/bash



# Syntaxes to remember:
#
# String length of a variable:  ${#varname}
# String offsetting of a variable: ${varname:offset} or ${varname:offset:length}


# Usage: pad_string LENGTH {PADDING_CHARACTER=' '}
function pad_string {
local line=''
local length=$1
local padding_character=' '
if [[ "$2" != "" ]]; then
padding_character=$2
fi
while((${#line} < $length)); do
line="$line$padding_character"
done
echo -n "$line"
}


# Usage: left_justify MESSAGE LENGTH {PADDING_CHARACTER=' '}
function left_justify {
local message=$1
local length=$2
local padding_character=' '
if [[ "$3" != "" ]]; then
padding_character=$3
fi
echo "$message$(pad_string $length-${#message} $padding_character)"
}


# Usage: right_justify MESSAGE LENGTH {PADDING_CHARACTER=' '}
function right_justify {
local message=$1
local length=$2
local padding_character=' '
if [[ "$3" != "" ]]; then
padding_character=$3
fi
echo "$(pad_string $length-${#message} $padding_character)$message"
}


# Usage: center_justify MESSAGE LENGTH {PADDING_CHARACTER=' '}
function center_justify {
local message=$1
local length=$2
local padding_character=' '
if [[ "$3" != "" ]]; then
padding_character=$3
fi
local half_length=$(expr $length / 2)
local half_message_length=$(expr ${#message} / 2)
local padding_length=$(expr $half_length - $half_message_length)
padding="$(pad_string $padding_length $padding_character)"
message="$padding$message$padding"
if [[ ${#message} > $length ]]; then # handle even/odd length issue
echo "${message:1}"
else
echo "$message"
fi
}