Wednesday, April 2, 2008

UNIX Script Goodness And Variable Prefix/Suffix Stripping Fun


Here's something you probably have no interest in, but it's a script I wrote to help me with UNIX shell programming that I engage in from time to time.

There's a nice way of easily taking a piece of text (often called a "String" by programmer-types) and stripping off pieces of it, either from the front or the back, using variable evaluation.

One thing to note about UNIX is that are many, many different ways to do the same thing. This is just one little feature of UNIX I like to use.

I wrote a script to help me when I want to do this prefix/suffix stripping kind of variable evaluation.

Here is the script in its entirety:


function showUsage {
print
print 'USAGE:'
print 'ksh -f variableTest.sh '
print
print '============================================================================================================='
print '${variable#pattern} evaluates variable, but removes the smallest portion of its prefix which matches pattern.'
print '${variable##pattern} evaluates variable, but removes the largest portion of its prefix which matches pattern.'
print '${variable%pattern} evaluates variable, but removes the smallest portion of its suffix which matches pattern.'
print '${variable%%pattern} evaluates variable, but removes the largest portion of its suffix which matches pattern.'
print '============================================================================================================='
print
print 'Special instructions:'
print '======================'
print 'To stop the shell from interpreting wildcards you may use for patterns,'
print 'run this script like the following:'
print
print 'ksh -f variableTest.sh '
print
print EXAMPLE: ksh -f variableTest.sh aabbcc \'a*\'
print
print
exit 1
}

clear

if [ $# -ne 2 ]
then
showUsage
fi

variable=$1
pattern=$2

print
print '============================================================================================================='
print '${variable#pattern} evaluates variable, but removes the smallest portion of its prefix which matches pattern.'
print '${variable##pattern} evaluates variable, but removes the largest portion of its prefix which matches pattern.'
print '${variable%pattern} evaluates variable, but removes the smallest portion of its suffix which matches pattern.'
print '${variable%%pattern} evaluates variable, but removes the largest portion of its suffix which matches pattern.'
print '============================================================================================================='
print
print 'variable: ' $variable
print 'pattern: ' $pattern
print
print '${variable#pattern} ' ${variable#$pattern}
print '${variable##pattern} ' ${variable##$pattern}
print '${variable%pattern} ' ${variable%$pattern}
print '${variable%%pattern} ' ${variable%%$pattern}



Most of this script is just printing stuff out to the screen. There's a whole big piece of code that just tells you how to run the script.

Anyways, say you want to find out what directory you are in on a UNIX file system, and want to save this off in a variable, but without all the nested subdirectories your directory rests in (UNIX is all about the nested subdirectories).

You can use this script to figure out the right pattern to get your current directory minus the path.

Example:

Let's say I'm in:
/usr/appl/abc/very/very/long/directory

After some trial and error running my script, I can eventually figure out how to get my current directory, minus the path.


>ksh -f variableTest.sh /usr/appl/abc/very/very/long/directory '*/'

variable: /usr/appl/abc/very/very/long/directory
pattern: */

${variable#pattern} usr/appl/abc/very/very/long/directory
${variable##pattern} directory
${variable%pattern} /usr/appl/abc/very/very/long/directory
${variable%%pattern} /usr/appl/abc/very/very/long/directory



Your current working directory (including the path) is stored in a variable called $PWD.

So, to get your current working directory only in a script you are writing, you can just write the following line:


MY_DIRECTORY=${PWD##*/}


Why did I write a script to do this? Because I can never remember how the pattern matching works, and thought it would be easier to write a script to show me instead.

Now, you're probably asking me, "Splotchy, why would you put something in a program that many, including you, do not fully understand or remember how it works?"

As Matty Boy would say, that's a great question, hypothetical question asker!

One thing that I neglected to mention about UNIX programming is that it is notoriously squirrelly. And this feature I am making use of is pretty damned squirrelly, too.

8 comments:

Rider said...

What's this post about now?

p0nk said...

ever tried to use the REGEX pattern matching class in .NET programming? Major PITA. I always have to find an example in a book, cut & paste, and then adjust by trial and error until i get it right.

Splotchy said...

As a matter of fact, I just did last week. I had to code the solution to a problem in .NET in a short period of time, and I didn't have any prior experience in .NET

So that was fun.

GETkristiLOVE said...

Wow, dude. You should just:

cd /pub
more beer

Matthew Hubbard said...

That took some man parts to publish, my man.

When I am at the poker table and someone asks me "Do you have a pair?", my answer is:

"Yes, I do, and they clank together when I walk."

I believe yours may be bigger and brassy-er, given this technical post.

Distributorcap said...

for once....

i have to say
huh?

Gupts said...

HI,

Thanks a lot for this..was trying to figure out pattern matching myself and this really helped.. Glad u hadnt deleted this..

Splotchy said...

I'm glad you got some use out of this, Gupts!