From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28030 invoked by alias); 7 Jul 2014 22:07:17 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 18932 Received: (qmail 9627 invoked from network); 7 Jul 2014 22:07:15 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 From: Bart Schaefer Message-id: <140707150625.ZM20692@torch.brasslantern.com> Date: Mon, 07 Jul 2014 15:06:25 -0700 In-reply-to: Comments: In reply to TJ Luoma "how do I get the last argument from a list of arguments?" (Jul 7, 5:06pm) References: X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: TJ Luoma , Zsh-Users List Subject: Re: how do I get the last argument from a list of arguments? MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Jul 7, 5:06pm, TJ Luoma wrote: } } I'm trying to learn better ways of dealing with arguments given to a } function, because I am sure that I am not doing it the most efficient } way. If the arguments are defined in a fairly regular way, zparseopts is probably the fastest method. E.g. your "for FOO" loop becomes something like: local -A opts zparseopts -A opts -D -E -M t:=-to -to: v=-verbose -verbose while [[ $1 = -* ]] do echo " $NAME [warning]: Don't know what to do with arg: $1" shift done # You can skip this part and use $opts[] directly, but: local TO=$opts[--to] VERBOSE=${opts[--verbose]+yes} With the -E -D -K flags you can call zparseopts multiple times if you want to (-E means skip over unspecified options, -D means remove the specified ones, and -K means to keep the results of previous calls). } That has worked OK for what I've needed to do, but now I'm trying to } create two functions which I will use in place of 'cp' and 'mv' and I } need to be able to find the _last_ argument (the destination) before I } process all the rest of the args. See Kurtis' reply regarding how to access arrays from the tail end. However, GNU cp/mv both take a --target= option so the directory name needn't be the last argument. So you could do something like zparseopts -E -D -A opts --target: if [[ -z $opts[--target] ]] then opts[--target]=$@[-1] shift -p fi That "shift -p" means to "pop" the last argument, in the "cp" example leaving $@ holding only the file names you are interested in copying.