ksh Multiple Pattern Matching Operators

I figured this would be simple, but I am stuck.

Variable longpath="/dir1/dir2/dir3/filename.stuff.morestuff.garbage"
I want to end up with just "filename.extra.moreextra". So, I want to get rid of the path and .garbage
I want to do this with just ksh internals. So, no sed,grep,awk,expr, etc...
I can do it with two operations.

longpath="/dir1/dir2/dir3/filename.stuff.morestuff.garbage"
a=${longpath##*/}; b=${a%.*} ; echo $b

How can I combine the two operations into one?

In fact, your command is good enough.

echo "/dir1/dir2/dir3/filename.stuff.morestuff.garbage" |awk -F "[/.]" '{print $(NF-3),$(NF-2),$(NF-1)}' OFS="."
1 Like

Hi.

The shell ksh does not allow nesting -- like this:

#!/usr/bin/env ksh

# @(#) s1	Demonstrate nested parameter expansion in shell.

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
pe() { for i;do printf "%s" "$i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { ( printf " db, ";for i;do printf "%s" "$i";done; printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && . $C

FILE=${1-data1}

pl " Original code:"
longpath="/dir1/dir2/dir3/filename.stuff.morestuff.garbage"
a=${longpath##*/}; b=${a%.*} ; echo $b

pl " Shortened code:"
longpath="/dir1/dir2/dir3/filename.stuff.morestuff.garbage"
echo ${${longpath##*/}%.*}

exit 0

producing:

% ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian GNU/Linux 5.0.7 (lenny) 
ksh 93s+

-----
 Original code:
filename.stuff.morestuff

-----
 Shortened code:
./s1: line 19: syntax error at line 20: `!' unexpected

and dash, bash shells will not allow nesting, however, zsh will:

% zsh s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian GNU/Linux 5.0.7 (lenny) 
zsh 4.3.6

-----
 Original code:
filename.stuff.morestuff

-----
 Shortened code:
filename.stuff.morestuff

Best wishes ... cheers, drl

1 Like

TYVM rdcwayx and drl.
I guess if I was going to use it enough and I am really 'lana' about using ksh internals, I could just write a function like this.

strip () {
    read -p "Input: " istring
    nopath=${istring##*/}
    noend=${nopath%.*}
    export ostring=$noend
}
strip $istring
echo $ostring

I think you're doing the right thing by gravitating towards ksh internal commands. This can really speed up your script by avoiding external processes. But you should not worry about using extra lines of code to accomplish this. It is still much faster than the overhead of forking another process. And rememeber that ksh compiles as it runs just like perl. If those two statements are in a loop, they will be read once... not once per iteration.