Finding the last arg
Bob McGowen x4312 dept208
bob at wyse.wyse.com
Thu Dec 27 09:44:52 AEST 1990
In article <18476 at shlump.nac.dec.com> lan_csse at netrix.nac.dec.com (CSSE LAN Test Account) writes:
>Well, it should have been easy, but everything I've tried has failed, so
>I'll go to the experts... (;-)
>
>What I've been trying to do is write a script whose semantics are sort of
>like the cp/mv/ln commands, in that the last argument is special. If it
>is a directory, I want to do something different that amounts to appending
>character strings to its name to give file name[s] within the directory;
>if it is an ordinary file, I just want to use its name.
>
>The problem is that I can't figure out any Bourne-shell expression that
>gives the last argument. In C-shell, it's easy (argv[$#]). But I need
>to write Bourne shell scripts. In fact, they need to be BSD bourne shell
>scripts rather that ATT Bourne shell scripts. The difference is probably
>significant here, because of the differences in the way these two Bourne
As an aside, could you explain this comment? I have had minimal contact
with BSD, but my experience does not seem to support this statement.
>shells handle variables. Actually, it'd be really nice to find a solution
>that is portable, but that may be just a dream.
---deleted discussion---
>Any ideas?
Three solutions came to mind: 1) using eval; 2) using shift; 3) using a
combined while loop/if statement with the shift.
1) eval echo this is the last argument \$$#
This works because the shell evaluates the right $ with the # to
give the last argument (not really, but see later), then re-reads
the line with the value of this number following the first $, which
it now sees as an unprotected character and gives the substituted arg
that matches. Now for the "not really": this will only work for
a list of args that is not bigger than nine. The tenth arg would
result in output like:
this is the last argument a0
where the a is arg 1 ($10 is the concatenation of $1 and 0).
2) shift `expr $# - 1`
echo the last arg is $1
The Bourne shell on AT&T's SysV/386 and the Sun OS support a
numeric argument to the shift. This number of args are shifted
out of the list. So if there are ten args, expr gives nine for
the shift, the last arg becomes $1. The problem here is that
all the preceding args are thrown away.
3) while [ ! -z "$1" ]
do
if [ $# -eq 1 ]
then
last=$1
shift
else
rest="$rest $1"
shift
fi
done
Each argument is collected as encountered on the command line
(except for the case where it contains white space -- "a b";
this is a little hard to handle with this type of structure
because the "arguments" are parsed three times: once as $1,
again in the if to construct the $rest and later whenever $rest
is used). All except the last are collected into the variable
rest, the last is in the variable last. You can now manipulate
the parts as needed. For instance, to create a path name
with the last arg as the first component:
for item in $rest
do
echo $last/$item
done
I hope this slightly lengthy discussion helps.
Bob McGowan (standard disclaimer, these are my own ...)
Product Support, Wyse Technology, San Jose, CA
..!uunet!wyse!bob
bob at wyse.com
More information about the Comp.unix.shell
mailing list