Simple bash toupper() and tolower() functions
Posted on | January 14, 2008 | 2 Comments
Many people aren’t aware of several built in macros available in the ‘tr’ program. The program, ‘tr’ stands for “translate or replace” and is available on any standard GNU/Linux distribution.
Using this simple utility, I wrote some simple shell functions to convert lower (or mixed) case strings to uppercase, or uppercase (or mixed) strings to lowercase. At the end of this post I’ll demonstrate why this is handy.
The following bash functions do what they say and say what they do (though they are portable beyond bash):
#!/bin/sh
toupper()
{
local char="$*"
out=$(echo $char | tr [:lower:] [:upper:])
local retval=$?
echo "$out"
unset out char
return $retval
}
tolower()
{
local char="$*"
out=$(echo $char | tr [:upper:] [:lower:])
local retval=$?
echo "$out"
unset out
unset char
return $retval
}
Then I called them like this :
test=$(toupper We Don\'t need no CrEdIt CaRd OfFeRs)
echo "$test"
unset test
test=$(tolower HEY, VISA - LEAVE OUR MAILBOXES ALONE!)
echo "$test"
The simple file with all of this is here. These are desirable because the functions don’t rely on regular expressions that might not be supported by whatever /bin/sh points to on any given computer.
In action, they produce the following:
WE DON’T NEED NO CREDIT CARD OFFERS hey, visa – leave our mailboxes alone!
Notice I used the POSIX invocation of the shell, as should you, keep things portable
Now on to why these are useful. I was writing a quick function to search the system’s PATH variable to find programs and output a file that could be sourced which defined globals to point to each program. Example is below:
check_prog()
{
local target="$1"
local dir=""
printf "Checking for the program %s ... " "$target"
for dir in $(echo $PATH | tr ':' ' '); do
[ -x ${dir}/${target} ] && {
printf "${dir}/${target} [ok]\n"
printf "\$_%s=\"%s\"\n" \
"$(echo $target | tr [:lower:] [:upper:])" "${dir}/${target}" >> paths.in
unset target dir
return 0
}
done
printf "[no]\n"
unset target dir
return 1
}
When I ran the following code:
check_prog "basename" || die prog "basename"
check_prog "dirname" || die prog "dirname"
check_prog "cp" || die prog "cp"
check_prog "readlink" || die prog "readlink"
check_prog "sed" || die prog "sed"
check_prog "cat" || die prog "cat"
check_prog "uname" || die prog "uname"
check_prog "install" || die prog "install"
check_prog "awk" || die prog "awk"
check_prog "grep" || die prog "grep"
check_prog "find" || die prog "find"
check_prog "gcc" || die prog "gcc"
check_prog "dialog" || true
The following file was produced, which is easily source()d or .’d by other shell scripts (just by grabbing paths.in):
tpost@tower:~/Desktop/unisetup.hg/libs $ cat paths.in
$_BASENAME="/usr/bin/basename"
$_DIRNAME="/usr/bin/dirname"
$_CP="/bin/cp"
$_READLINK="/bin/readlink"
$_SED="/bin/sed"
$_CAT="/bin/cat"
$_UNAME="/bin/uname"
$_INSTALL="/usr/bin/install"
$_AWK="/usr/bin/awk"
$_GREP="/bin/grep"
$_FIND="/usr/bin/find"
$_GCC="/usr/bin/gcc"
$_DIALOG="/usr/bin/dialog"
Very handy
So I thought I’d share. The functions listed above are hereby donated to the public domain in hopes that they save you from pulling your hair out while doing something.
Rather than calling `which program’, just call $_PROGRAM
Type “man tr” from your command prompt to see more fun things you can do with the program. So many people fork sed in a pipe when something much smaller will do
My “die” function simply switches argv[1] to know what we’re complaining about and examples argv[2] to be specific.
Also note, I escaped all ticks in the strings. This could also be automagically done by ‘tr’. Have fun with it. Of course, to be portable, you should first check to make sure ‘unset’ works. That’s for some other post in the future. I used printf because not all POSIX (/bin/sh) invocations of all shells support extra stuff (i.e. \t \n), echo -e or echo -n might not work on smaller shells like dash.
Forgive the lack of formatting, WordPress “code” tags are brain dead.
Comments
2 Responses to “Simple bash toupper() and tolower() functions”
Leave a Reply

January 26th, 2008 @ 4:06 pm
Note: busybox’s built in ‘tr’ lacks the [:upper:] and [:lower:] macros. If you know your strings are going to be in a western-en charset, just use tr ‘a-z’ ‘A-Z’.
Otherwise, you’ll need to ensure that ‘blah-blah’ is effective for all languages that you hope to support.
April 15th, 2010 @ 1:01 pm
You guys! Just use BASH
$ var=”hello world” $ echo ${var^^} HELLO WORLD $ echo ${var^} Hello world