Thanks to all who respond to my questions on mv *.abc *.xyz!!!

Alvaro Hui Kau rcoahk at chudich.co.rmit.oz
Mon Sep 10 15:30:34 AEST 1990


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 at 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 at wimsey.bc.ca (J.T. Conklin)

for i in *.xyz
do
	mv $i `basename $i xyz`abc
done

From: petej%mips.com at 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 at 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 at 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 at 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 at 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 at msi.umn.edu (Jason Molenda)

in csh it's even easier

foreach i ( *foo ) 
   mv $i {$i:r}.bar
end

From: mcdaniel at 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 at uiucdcsm.cs.uiuc.edu in
# uicsrd.csrd.uiuc.edu:comp.sources.d */
# Here is my rename script.
#
# Dan LaLiberte
# liberte at 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 at ins.CWRU.Edu		

From: keith at 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 at 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 at 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 at 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 at mullian.oz
    4th Year B.E.\ B.Sc.	|Internet &	akkh at mullian.ee.mu.OZ.AU
   University of Melbourne	|Arpanet	rcoahk at koel.co.rmit.OZ.AU 



More information about the Comp.unix.misc mailing list