Shell Tips – how to cut substring?

Although a awk has some string function such as substr, I write a sh function to cut sub string which you specific.

Usage: strcut $String $SubCut


strcut "Goodshell" "shell"

It will print "Good"



strcut ()

if [ $# != 2 ]; then
    #echo "Argument error!"; 1>&2
    return 1
newStr=`echo $strSrc |  awk ‘{if ($0~/’$strSub’$/) { len=length($0)-length(Sub); print substr($0, 1, len)} }’  Sub=$strSub`

if [ "$newStr" = "" ]; then
    #echo "Cannot cut"; 1>&2
    return 1
    echo $newStr
    return 0

strcut $1 $2


9 thoughts on “Shell Tips – how to cut substring?

  1. Yes, there is a way in Bourne Shell (sh) using built-ins only, but why bother when better shells are around? That way would be to use a while loop with a case statement where each case matches against <character>* and accumulate that character until you find that the accumulated string concatenated with the strSub argument equals strSrc or you run out of characters.

  2. sub () {
    case "$orig" in
    *${suffix}) :;;
    *) echo "Error: $2 not a suffix of $1" 1>&amp;2; return 1;;
    while :
    case "$orig" in
    ${prefix}${suffix}) finished=:; break;;
    ${prefix}a*${suffix}) prefix=${prefix}a;;
    # ...
    ${prefix}z*${suffix}) prefix=${prefix}z;;
    *) break;;
    if $finished
    echo "PREFIX=$prefix"
    return 0
    echo "Error: something went wrong -- probably not enough arms in the case statement" 1>&amp;2
    return 1
  3. Actually, my version uses one non-built-in: /bin/false. I think that’s OK :), but you could always fix it so it doesn’t.
    The need for a case/esac arm for every character you could match makes this function very long, but it does show what you can do with Bourne Shell glob matching and the case statement (er, actually, it’s a “command” according to the man page, though built-in)!
    BTW, my knowledge of what can be done with bare-bones Bourne Shell comes from the old SunOS 4.x days when separate / and /usr partitions were de rigeur — add ODS and often there’d be problems where the OS would stop booting and drop into single-user mode with / mounted read-only and /usr not mounted at all. Knowing the ins and outs of Bourne Shell programming in such situations was very useful! Someone (or was it a magazine article? I forget) showed me how to cat files with sh but without cat and I never looked at shell scripting the same way again.

  4. AFAIK both solutions (using shell builtin commands and awk/sed filters) are correct, however keep following rule in mind:
    – Only use external filters if you have _lots_ of data (e.g. at least more than one CPU page (e.g. /usr/bin/pagesize)) of data to pass through the filters, otherwise the |fork()|+|exec()| overhead costs too much CPU time.

    See also the draft for the shell style guide section
    Only use external filters like grep/sed/awk/etc. if you want to process lots of data with them


Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s