Wednesday, February 11, 2009

The Power of Bash Shell

Recently I borrowed Shell Scripting Recipes: A Problem-Solution Approach from our National Library and found the book extremely useful. Unlike other shell scripting books which started off with a lot basic stuff, it goes straight to solving problems. Also, the author really spent a lot of time trying to explore builtin capabilities of shells ( bash, ksh, ...). By using builtin features, you can avoid running separate processes to handle a particular operation. This will improve your shell script performance tremendously.

In this blog, I will show you some of them and it's equivalent in sh

fname="/some/where/dir/file.txt"
str="to be or not to be"

bash/kshshOutput
$((9*8+7)) expr 9 \* 8 + 7 79
${fname%/*} dirname $fname /some/where/dir
${fname##*/} basename $fname file.txt
${#str} echo -n $str | wc -c 18
${str%be*} echo $str | perl -pe 's/(.*)be.*?/\1/' to be or not to
${str%%be*} echo $str | sed -e 's/be.*$//' to
${str#to*} echo $str | perl -pe 's/to.*?//' be or not to be
${str##to*} echo $str | sed -e 's/^to.*//'
${str:7} echo $str | awk '{print substr($0,8)}' r not to be
${str:0:7} echo $str | awk '{print substr($0,0,7)}' to be o
${str/be/BE} echo $str | sed -e 's/be/BE/' to BE or not to be
${str//be/BE} echo $str | sed -e 's/be/BE/g' to BE or not to BE

With the above builtin features in bash, you can do quite a few things in shell scripting as shown in the book. BTW, here is a bash script demonstrates all of the above features and some practical usages:

$ cat a.sh
#! /bin/bash


fname="/some/where/dir/file.txt"
echo -e '$fname'        "\t"    $fname
echo -e '${fname%/*}'   "\t"    ${fname%/*}
echo -e '${fname%%/*}'  "\t"    ${fname%%/*}
echo -e '${fname#*/}'   "\t"    ${fname#*/}
echo -e '${fname##*/}'  "\t"    ${fname##*/}

echo

# number calaculation
echo -e 'i=$((21 + 32))'        "\t"    ; i=$((21+32))
echo -e '$((++i))'              "\t"    $((++i))
echo -e 'i*7+3 $((i*7+3))'      "\t"    $((i*7+3))

echo

# string manipulation
str="to be or not to be"
echo -e '$str'          "\t"    \"$str\"
echo -e '${#str}'       "\t"    \"${#str}\"
echo -e '${str%be*}'    "\t"    \"${str%be*}\"
echo -e '${str%%be*}'   "\t"    \"${str%%be*}\"
echo -e '${str#to*}'    "\t"    \"${str#to*}\"
echo -e '${str##to*}'   "\t"    \"${str##to*}\"
echo -e '${str:7}'      "\t"    \"${str:7}\"
echo -e '${str:0:7}'    "\t"    \"${str:0:7}\"
echo -e '${str/be/BE}'  "\t"    \"${str/be/BE}\"
echo -e '${str//be/BE}' "\t"    \"${str//be/BE}\"


echo -e "\n\nPractical use:\n"

# underline
echo $str
echo ${str//?/=}

# remove leading 0s
echo -e month=03        "\t"    ; month=03
echo -e '${month#0}'    "\t"    ${month#0}

$ ./a.sh
$fname   /some/where/dir/file.txt
${fname%/*}      /some/where/dir
${fname%%/*}
${fname#*/}      some/where/dir/file.txt
${fname##*/}     file.txt

i=$((21 + 32))
$((++i))         54
i*7+3 $((i*7+3))         381

$str     "to be or not to be"
${#str}          "18"
${str%be*}       "to be or not to "
${str%%be*}      "to "
${str#to*}       " be or not to be"
${str##to*}      ""
${str:7}         "r not to be"
${str:0:7}       "to be o"
${str/be/BE}     "to BE or not to be"
${str//be/BE}    "to BE or not to BE"


Practical use:

to be or not to be
==================
month=03
${month#0}       3

Labels: ,

0 Comments:

Post a Comment

<< Home