From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10146 invoked from network); 16 Jun 2000 21:00:54 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 16 Jun 2000 21:00:54 -0000 Received: (qmail 4621 invoked by alias); 16 Jun 2000 21:00:34 -0000 Mailing-List: contact zsh-users-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 3175 Received: (qmail 4607 invoked from network); 16 Jun 2000 21:00:32 -0000 From: "Bart Schaefer" Message-Id: <000616140019.ZM4608@candle.brasslantern.com> Date: Fri, 16 Jun 2000 14:00:19 -0700 In-Reply-To: <20000616145330.A8031@scowler.net> Comments: In reply to Clint Adams "more fun with parameter expansion" (Jun 16, 2:53pm) References: <20000616145330.A8031@scowler.net> X-Mailer: Z-Mail Lite (5.0.0 30July97) To: Clint Adams , zsh-users@sunsite.auc.dk Subject: Re: more fun with parameter expansion MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii On Jun 16, 2:53pm, Clint Adams wrote: > Subject: more fun with parameter expansion > This is for someone who wants to take a directory tree and convert all > the filenames (and directory names) to lowercase, replacing spaces > with underscores. It presumes that you are using GNU mv and have > MARK_DIRS set. I'm sure that someone can make it more efficient. I dunno about efficient, but you can do it with only one glob and one loop, and it doesn't need to care about MARK_DIRS. Oh, and your solution missed file names that began with a dot, unless you meant to say that both MARK_DIRS and GLOB_DOTS were needed ... for f in **/*(DNon); do mv -v $f ${${(M)f%/*}:+${${f%/*}:l:gs/ /_/}}${${${(M)f%/*}:-$f}:l:gs/ /_/} done The `(on)' (order by name) is probably unnecessary, and won't work in 3.0.x (though everything else should). Writing that one-liner out a bit longer might make this more readable: t=${(M)f%/*} # The tail of the path, including leading slash h=${t:+${f%/*}} # The head of the path if the tail is non-empty t=${t:-$f} # The tail is the path when the tail is empty h=$h:l # Downcase the head, same as ${(L)h} t=$t:l # Downcase the tail h=$h:gs/ /_/ t=$h:gs/ /_/ mv $f $h$t The last five steps could be written as mv $f ${${:-$h$t}:l:gs/ /_/} Do you see what that's doing? Exercise: Rewrite the "mv" in my for-loop with that trick, to make it at least 8 characters shorter. Incidentally, you can turn on MARK_DIRS for individual globs like this: echo *(M)