rcoahk@chudich.co.rmit.oz (Alvaro Hui Kau) (09/10/90)
The subject said it all. Thanks very for all those who take the time to answer my questions!! The response are overwhelming!! Here are the replies : From: "Kristoffer H. Holm" <kris%diku.dk@munnari.oz> It is quite simple (depending on what shell you use) to write a shell script. If you use the Bourne Shell ("sh") then this shell script ("mvstar") should do the trick (the first line starts with a ":", the last is the line "exit"): : 'mvstar s1 s2: move files with suffix .s1 into files with suffix .s2' # First we bark if not exactly 2 arguments were given (see the manual pages sh(1) [for if] and test(1) for details). # if test $# -ne 2 then echo Usage: $0 suffix1 suffix2 exit 2 fi # Next we run through all the files *.$1, that is with # suffix as the first argument, and "mv" them to the file # name gotten by concatenating the prefix part with the # other suffix (see the manual page expr(1) for details). # for file in *.$1 do mv $file `expr "$file" : "\(.*\)\.$1"`.$2 done exit The comment-lines (starting with a "#") says most; the relevant manual pages are in the Users Manual. From: jtc@wimsey.bc.ca (J.T. Conklin) for i in *.xyz do mv $i `basename $i xyz`abc done From: petej%mips.com@munnari.oz (Pete Johnson) I just use sed to generate a bunch of copy commands and then pipe it into csh. For example, % ls *.xyz | sed 's/\(.*\)\.xyz/cp \1.xyz \1.abc' | csh So, ls generates a list of all of the files to copy. Sed generates the cp command (look in the sed or ed documentation for a description of regular expressions). For example, if sed were given "foo.xyz" on a line, it would generate "cp foo.xyz foo.abc". Lastly, each cp command is given to a shell to be executed. From: wuxing%comp.mscs.mu.edu@munnari.oz (Xing Wu) try something like ls | while read a do i=`basename $a .xyz` mv $i.xyz $i.abs done or some variation on the theme. 'basename' will give you the name of a file without the second argument (i.e., 'basename file1.ext .ext' evaluates to 'file1'). From: peter@cm.deakin.OZ.AU (Peter Horan) A script would go something like this: for file $* do bname = `basename $file` mv $file $bname.xyz done From: lrb@rrivax.rri.uwo.ca (Lance R. Bailey) # changing *foo to *bar for i in *foo do j=`echo $i | sed -e 's/foo/bar/'` mv $i $j done From: de5@de5.CTD.ORNL.GOV (Dave Sill) I picked this up on comp.unix.wizards a few years back. Typical uses: mved lib=.a =.a moves libhello.a to hello.a mved =.o =.o.old moves fred.o to fred.o.old mved '=.*' = moves fred.junk to fred mved =.sh = moves mved.sh to mved mved *.sh =. #! /bin/sh # mved.sh # Move-and-edit filenames. # # Usage: mved [-n] from-pattern to-pattern # # This command allows you to change file names much as is possible # with some versions of PIP (remember *.txt=*.bak?). # The '=' character in from-pattern is treated as a special wildcard, # matching in the same way as the shell '*' wildcard character, except # that the text matching the '=' in the first pattern is inserted in # place of any = wildcards in the second. # Note that from-pattern need not have a wildcard if to-pattern does, # a default # # Use the '-n' option to do nothing, showing what would be done. # # Restrictions: # Only the first '=' sign in from-pattern is used. Multiple = # wildcards in from-pattern match up with the first from-pattern # =, ie: there is no matching for multiple = signs. (I'm sure # someone could make it work if they wanted to... ?) # # eg: mved lib=.a =.a moves libhello.a to hello.a # mved =.o =.o.old moves fred.o to fred.o.old # mved '=.*' = moves fred.junk to fred # mved =.sh = moves mved.sh to mved # mved *.sh =. # # Brian Coogan 06 Jan 87 # Hewlett-Packard Australian Software Operation # $Header$ ASO shopt=x case "$1" in -n) shopt=vn; shift ;; esac # Check for appropriate wildcards. # Source must have an = or a * wildcard or already exist. case "$1" in *=*) ;; *) for n in $1 do if [ ! -f "$n" ] then echo "$0: No files match from-pattern!\n" 1>&2 set -- "$@" give usage message elif [ "$2" = '=' ] then echo Nothing doing. exit 0 fi break done ;; esac case "$2" in *=*) ;; *) echo "$0: No '=' wildcards used in target!\n" 1>&2 set -- "$@" give usage message ;; esac # catch mved = = case "$1$2" in ==) echo Nothing doing.; exit 0;; esac if [ $# -ne 2 ] then echo "Usage: $0 [-n] from-pattern to-pattern" 1>&2 echo "\tEquals (=) signs in the to-pattern match like '*' and are" echo "\treplaced with the text that matched the = in from-pattern." echo "\tYou must quote any '*'s in from-pattern." exit 1 fi globpatt=`echo $1 | sed 's/=/\*/'` frompatt=`echo "$1" | sed \ -e 's/\./\\\\./g' \ -e 's/\*/.*/g' \ -e 's/=/\\\\(\\.\\*\\\\)/' \ -e '/\\\\(/ !s/.*/\\\\(&\\\\)/' ` topatt=`echo "$2" | sed -e 's/=/\\\\1/g'` for n in $globpatt do # Check the pattern got expanded. (The file might also have vanished). if [ ! -f $n ] then echo "$0: No files matching $1 found." 1>&2 exit 1 fi echo $n done | sed -n "s;$frompatt;mv & $topatt;p" | sh -$shopt echo done From: molenda@msi.umn.edu (Jason Molenda) in csh it's even easier foreach i ( *foo ) mv $i {$i:r}.bar end From: mcdaniel@adi.com (Tim McDaniel) This is from Dan LaLiberte of the University of Illinois at Urbana-Champaign. I've used it for years. The conversion to Bourne-shell syntax should be obvious. Usage is like rename 's/\.xyz$/abc/' *.xyz #! /bin/csh -f #/* Written 7:36 pm May 29, 1988 by liberte@uiucdcsm.cs.uiuc.edu in # uicsrd.csrd.uiuc.edu:comp.sources.d */ # Here is my rename script. # # Dan LaLiberte # liberte@a.cs.uiuc.edu # uiucdcs!liberte # # --- # # rename files with a sed command. File names may have spaces in them. if ($#argv < 2) then echo "Usage: rename sed-command file ..." exit (1) endif set command = "$1" shift set noglob while ($#argv > 0) set name = ($argv[1]) shift set newname = `echo "$name" | sed -e "$command"` if ($status != 0) exit 1 echo "mv -i $name $newname" mv -i "$name" "$newname" end exit 0 # /* End of text from uicsrd.csrd.uiuc.edu:comp.sources.d */ In bash or ksh, it's just as easy: cwns1$ ls 1.foo 2.foo 3.foo 4.foo 5.foo 6.foo 7.foo 8.foo 9.foo cwns1$ for i in *.foo > do > mv $i ${i%.*}.bar > done cwns1$ ls 1.bar 2.bar 3.bar 4.bar 5.bar 6.bar 7.bar 8.bar 9.bar Chet chet@ins.CWRU.Edu From: keith@sequoia.execu.com (Keith Pyle) OK, so it's not done with the shell, but the program mmv posted to comp.sources.unix (Volume 21, Issue 87) does this and a good deal more. With mmv, the method would be: mmv '*.xyz' '=1.abc' Here's a bit of the man page: NAME mmv - move/copy/append/link multiple files by wildcard pat- terns SYNOPSIS mmv [-m|x|r|c|o|a|l|s] [-h] [-d|p] [-g|t] [-v|n] [from to] DESCRIPTION Mmv moves (or copies, appends, or links, as specified) each source file matching a from pattern to the target name specified by the to pattern. This multiple action is per- formed safely, i.e. without any unexpected deletion of files due to collisions of target names with existing filenames or with other target names. Furthermore, before doing any- thing, mmv attempts to detect any errors that would result from the entire set of actions specified and gives the user the choice of either proceeding by avoiding the offending parts or aborting. -- From: hunt@dg-rtp.dg.com (Greg Hunt) There are no stupid questions. Just ones you don't know the answers to yet. This is how I change the names of files like you need to in the Bourne shell: for tmp in $* ; do mv $tmp `basename $tmp .xyz`.abc done The basename program returns just the file name portion of a pathname, and optionally removes a suffix. Since there is no pathname portion if you're in the directory the files exist in, all that this example does is to remove the suffix. Then it puts on the new suffix, and the files get renamed the way you want. Put the above lines into a file named whatever you want with an editor. Exit the editor. Then type 'chmod 755 your_script_name'. This changes the file permissions to user{read,write,execute}, group{read,execute}, other{read,execute}. The "execute" permission is the key to being able to run shell scripts. To use the script, type: your_script_name *.xyz As you learn more about scripts, you can make it more general by allowing you to specify the old and new suffixes as arguments to the script as well (hint - look at the shift shell command and specify the old and new suffixes as the first two arguments). Enjoy! -- From: lmiller@aerospace.aero.org (Lawrence H. Miller) One way to do this is to use basename. Try something like this (for you specific case of changing *.xyz to *.abc). (This is a Bourne shell script.) ------------------------------ CUT HERE ------------------------------ for i in *.xyz do a=`basename $i .xyz` echo moving $a.xyz to $a.abc mv $a.xyz $a.abc done From: tchrist@convex.COM (Tom Christiansen) I still like this one (from the FAQ): #!/usr/bin/perl # # rename script examples from lwall: # rename 's/\.orig$//' *.orig # rename 'y/A-Z/a-z/ unless /^Make/' * # rename '$_ .= ".bad"' *.f # rename 'print "$_: "; s/foo/bar/ if <stdin> =~ /^y/i' * $op = shift; for (@ARGV) { $was = $_; eval $op; die $@ if $@; (rename($was,$_) || warn "$0: can't rename $was to $_: $!\n") if $was ne $_; } -- =============================================================================== Alvaro Hui |ACSnet akkh@mullian.oz 4th Year B.E.\ B.Sc. |Internet & akkh@mullian.ee.mu.OZ.AU University of Melbourne |Arpanet rcoahk@koel.co.rmit.OZ.AU