[comp.unix.questions] simple question about mv

DEG41560@ua1vm.ua.edu (Rob Smith) (01/27/89)

HI,

 I know this is simple, but then again, so am I.  What if I want to mv a bunch
of files with the same suffix to another suffix. The following does not
work

    mv *.flip *.flop

what does?  I'm under Ultrix 2.2.  I'm doing it by hand, but I'd like to
be able to do wild card renames, ala DOS.


                                         Thanks,
                                            Rob.

dcmartin@cs.wisc.edu (David C. Martin) (01/28/89)

foreach i ( *.flip )
mv $i $i:r.flop
end

dcm

moss@BRL.MIL (VLD/VMB) (01/28/89)

< I know this is simple, but then again, so am I.  What if I want to mv a bunch
< of files with the same suffix to another suffix. The following does not
< work
< 
<    mv *.flip *.flop
Well, this should work under a Bourne shell:
$ for i in *.flip
> do	mv $i `basename $i .flip` .flop
> done
$
-moss

ark@alice.UUCP (Andrew Koenig) (01/28/89)

In article <18216@adm.BRL.MIL>, DEG41560@ua1vm.ua.edu (Rob Smith) writes:
>  I know this is simple, but then again, so am I.  What if I want to mv a bunch
> of files with the same suffix to another suffix. The following does not
> work
> 
>     mv *.flip *.flop

If you give a bunch of operands to mv, the last one must be a directory
and all the others are moved into that directory.  Thus the last
(in alphabetical order) thing with a name of *.flop becomes the
target directory and everything else winds up thee.

This is almost surely not what you want.

To get what you want, try this:

	for i in *.flip
	do	mv $i `echo $i | sed 's/flip$/flop/'`
	done
-- 
				--Andrew Koenig
				  ark@europa.att.com

les@chinet.chi.il.us (Leslie Mikesell) (01/28/89)

In article <18216@adm.BRL.MIL> DEG41560@ua1vm.ua.edu (Rob Smith) writes:
>HI,

> I know this is simple, but then again, so am I.  What if I want to mv a bunch
>of files with the same suffix to another suffix. The following does not
>work

>    mv *.flip *.flop

>what does?  I'm under Ultrix 2.2.  I'm doing it by hand, but I'd like to
>be able to do wild card renames, ala DOS.

Unlike DOS file extensions, the '.' is just another character to unix.
How about:  (using /bin/sh)

for i in *.flip
do
mv $i `sed -e 's/flip$/flop'`
done

It might be easier to arrange to have flip and flop subdirectories instead
of using the file suffix since it is a bit easier to:
  mv flip/* flop
and generally no more difficult to construct the full pathname.

Les Mikesell

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/28/89)

In article <18216@adm.BRL.MIL> DEG41560@ua1vm.ua.edu (Rob Smith) writes:
>    mv *.flip *.flop

Since filename expansion is performed by the shell, not by the "mv"
utility, for the shell to directly do what you're attempting it would
have to know the semantics of "mv".  That is contrary to the design
principles of the UNIX shell.

If you have a "basename" utility, try something like:
	for i in *.flip
	do	mv $i `basename $i .flip`.flop
	done
Notice how much more general this approach is.

guy@auspex.UUCP (Guy Harris) (01/28/89)

>Well, this should work under a Bourne shell:
>$ for i in *.flip
>> do	mv $i `basename $i .flip` .flop
...

Assuming, of course, that all the files are in the current directory,
since "basename" will not only strip off the ".flip", but will also
strip off all the directories leading up to the name (i.e., it will turn
"/usr/src/nemo/cigar.flip" into "cigar", not into
"/usr/src/nemo/cigar"). 

If your system has "dirname", which will strip off the last component of
the name and give you the directory in question, you can use that if
need be.

merlyn@intelob.intel.com (Randal L. Schwartz @ Stonehenge) (01/29/89)

In article <18231@adm.BRL.MIL>, moss@BRL (VLD/VMB) writes:
| Well, this should work under a Bourne shell:
| $ for i in *.flip
| > do	mv $i `basename $i .flip` .flop
| > done
| $

Almost.  Don't try this at home, kiddies.  Remove the space before
".flop", or you'll end up with something very unintended.

Try this:

$ for i in *.flip; do mv $i `basename $i .flip`.flop; done

Presto-magico.
-- 
Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095
on contract to BiiN (for now :-), Hillsboro, Oregon, USA.
ARPA: <@iwarp.intel.com:merlyn@intelob.intel.com> (fastest!)
MX-Internet: <merlyn@intelob.intel.com> UUCP: ...[!uunet]!tektronix!biin!merlyn
Standard disclaimer: I *am* my employer!
Cute quote: "Welcome to Oregon... home of the California Raisins!"

nolan@tut.cis.ohio-state.edu (Michael C. Nolan) (01/29/89)

In article <18216@adm.BRL.MIL> DEG41560@ua1vm.ua.edu (Rob Smith) writes:
>
> I know this is simple, but then again, so am I.  What if I want to mv a bunch
>of files with the same suffix to another suffix. 

There is a program rename available by anonymous ftp from csli.stanford.edu 
in the directory pub/Gandalf.  It seems to work fine for me, and does what
you want and a bit more, like convert case, etc.  It looks like
rename suff1=suff2 *.suff1

-Mike

-- 
nolan@hiips.lpl.arizona.edu;   ...!noao!solpl!hiips

leo@philmds.UUCP (Leo de Wit) (01/29/89)

In article <7558@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes:
|In article <18216@adm.BRL.MIL> DEG41560@ua1vm.ua.edu (Rob Smith) writes:
|>HI,
|
|> I know this is simple, but then again, so am I.  What if I want to mv a bunch
|>of files with the same suffix to another suffix. The following does not
|>work
|
|>    mv *.flip *.flop
|
|>what does?  I'm under Ultrix 2.2.  I'm doing it by hand, but I'd like to
|>be able to do wild card renames, ala DOS.

This seems a popular simple question. We had it last year (with its
endless discussions, of which I'm guilty too 8-). Any chance that this
one is added to the 'list of simple questions & answers', Chris?

|Unlike DOS file extensions, the '.' is just another character to unix.
|How about:  (using /bin/sh)
|
|for i in *.flip
|do
|mv $i `sed -e 's/flip$/flop'`
|done

You probably meant here:

mv $i `echo $i|sed -e 's/flip$/flop/'`

As it stands, the sed command has no input (well, not what you expect
it to have), and the sed expression contains a syntax error.

Suggestion: move the sed command to the for command, so that you can do
all substitutions all at once:

for i in `echo *.flip|sed 's/\.flip / /g;s/\.flip$//'`
do
	mv $i.flip $i.flop
done

Or, without a loop:

apply 'mv %1.flip %1.flop' `echo *.flip|sed 's/\.flip / /g;s/\.flip$//'`

(Apply(1) is probably BSD-only).

Or:

apply 'mv %1.flip %1.flop' `ls *.flip|sed 's/\.flip$//'`

Or:

(etc, etc, ... )

	 Leo.

bill@cosi.UUCP (Bill Michaelson) (01/30/89)

In article <18216@adm.BRL.MIL>, DEG41560@ua1vm.ua.edu (Rob Smith) writes:
> ..The following does not work
> 
>     mv *.flip *.flop
> 
> what does?  I'm under Ultrix 2.2.  I'm doing it by hand, but I'd like to
> be able to do wild card renames, ala DOS.

You should be aware that the mv command never even sees the asterisks
because the shell expands the wildcard into a list of files BEFORE passing
the argument list to the command.  What this amounts to is that the last
file in the expanded list becomes the target, and receives the contents
of all the other files in the expanded list.  Assuming there are no *.flop
files in the current directory,  you will effectively screw-up the last *.flip.

I can think of a partial solution to your problem, but being somewhat of a
novice at this business, it doesn't do exactly what you asked for.  Perhaps
someone else will jump in and help me out.  Try something like:

find . -name "*.flip" -exec mv {} {}.flop \;

This has three problems:

1) It appends '.flop' to the end of the names of the files, without
   dropping the .flip.  How does one get a substring in Bournese?

2) It walks through lower directories, which may be a problem.  Is there
   a way to prevent find from doing this?

3) I haven't tried it, so I'm not 100% certain it will do what I say.

Hmmm...  Come to think of it, I don't like my suggestion at all.  Oh well.
Food for thought, anyway.

-- 
Bill Michaelson - uh... princeton!mccc!cosi!bill, I think.
also at... Voice 609-771-6705  CompuServe 72416,1026

moss@BRL.MIL (VLD/VMB) (01/30/89)

Guy Harris writes:
>>Well, this should work under a Bourne shell:
>>$ for i in *.flip
>>> do   mv $i `basename $i .flip` .flop
> ...
>
>Assuming, of course, that all the files are in the current directory,
>since "basename" will not only strip off the ".flip", but will also
>strip off all the directories leading up to the name (i.e., it will turn
>"/usr/src/nemo/cigar.flip" into "cigar", not into
>"/usr/src/nemo/cigar").
Well, first off, I made a typo, though I really did test this out first,
alas I typed it wrong in the note, it should be:

	mv $i `basename $i .flip`.flop    # note, no space after 2nd `

Secondly, although Guy is correct that this does not work in general, it
*does* work as a solution to the original question; how to do:

	mv *.flip *.flop

I actually used 'sed' first which is more general, but thought that this
was easier for the novice to understand.
-moss

les@chinet.chi.il.us (Leslie Mikesell) (01/31/89)

In article <940@philmds.UUCP> leo@philmds.UUCP (Leo de Wit) writes:
>|for i in *.flip
>|do
>|mv $i `sed -e 's/flip$/flop'`
>|done
>
>You probably meant here:
>
>mv $i `echo $i|sed -e 's/flip$/flop/'`
>
>As it stands, the sed command has no input (well, not what you expect
>it to have), and the sed expression contains a syntax error.

Oops, I even tested that and then mistyped it.  What I actually would
have done myself (assuming that it doesn't need to be done often enough
to be worth writing a shell script) is:
vi
:r !ls *.flip
:%s/.*/& &/ 
:%s/flip$/flop/
:%s/^/mv /
:w !sh
:q!

This lets me check my notoriously poor typing before anything actually
happens and each step can be undone with the <u> command if it doesn't
look right.  Now, how many people have a vi manual that documents the
difference between :w! file and :w !command ?

Les Mikesell

jon@jonlab.UUCP (Jon H. LaBadie) (02/01/89)

In article <4093@omepd.UUCP>, merlyn@intelob.intel.com (Randal L. Schwartz @ Stonehenge) writes:
In article <18231@adm.BRL.MIL>, moss@BRL (VLD/VMB) writes:
| Well, this should work under a Bourne shell:
| $ for i in *.flip
| > do	mv $i `basename $i .flip` .flop
| > done
| $

Randal and others (this is not intended to pick on Randal's suggestion)
have proposed work-arounds to UNIX's command line interpreters (or to
mv's) deficiency in wild card matching.  Each have proposed a separate
mv command for each file.  This is unfortunate, but probably necessary.

However, each suggestion has also necessitated a separate process such
as cut, sed, or in Randal's case, basename, for each file to be moved.
An alternative, is one command line to create a list of "root names"
and loop through them.  For a large number of files, this could
greatly enhance the efficiency of the processing.  Ksh users could
improve upon this even more using the special substitution facilities
of that shell.

	for root in `ls *.flip | cut -d. -f1`
	do
		mv ${root}.flip ${root}.flop
	done

Potential problems still exist if a) two "."s are int the file names,
or b) not ".flip" files exist.

Isn't UNIX great?  :-)  for guru's!  ;-)
-- 
Jon LaBadie
{att, ulysses, princeton, bcr}!jonlab!jon

root@libove.UUCP (Jay M. Libove) (02/02/89)

From article <18216@adm.BRL.MIL>, by DEG41560@ua1vm.ua.edu (Rob Smith):
> HI,
> 
>  I know this is simple, but then again, so am I.  What if I want to mv a
> bunch of files with the same suffix to another suffix. The following does
> not work
> 
>     mv *.flip *.flop
> 
> what does?  I'm under Ultrix 2.2.  I'm doing it by hand, but I'd like to
> be able to do wild card renames, ala DOS.
> 
>                                          Thanks,
>                                             Rob.

Some time back (the files are copyright 1986), mcvoy@cs.wisc.edu wrote
a pair of utilities called "move" and "copy" which would work as:

% ls *.flip
a.flip b.flip cc.flip dddd.flip e.flip
% move =.flip =.flop
mv a.flip a.flop
mv b.flip b.flop
mv cc.flip cc.flop
mv dddd.flip dddd.flop
mv e.flip e.flop
%

I am pretty sure that it is in the comp.sources.misc or comp.sources.unix
archives, but if you can't find it, then I can mail it or it can be
fetched off of my machine (by prior arrangement).
-- 
Jay Libove		jl42@andrew.cmu.edu, libove@cs.cmu.edu,
5731 Centre Ave, Apt 3	sei.cmu.edu!libove!libove, jl42@andrew.BITnet,
Pittsburgh, PA 15206	jl42@drycas.BITnet, psuvax1!pitt!darth!libove!libove,
(412) 362-8983		or uunet!nfsun!libove!libove

gwc@root.co.uk (Geoff Clare) (02/02/89)

In article <18216@adm.BRL.MIL> DEG41560@ua1vm.ua.edu (Rob Smith) writes:
>
>What if I want to mv a bunch
>of files with the same suffix to another suffix. The following does not
>work
>
>    mv *.flip *.flop
>
>what does?  I'm under Ultrix 2.2.  I'm doing it by hand, but I'd like to
>be able to do wild card renames, ala DOS.
>

The following is a 'rename' script which I find very useful. It allows
you to apply any 'sed' command to a list of files.  To safeguard
against duplicate new names it does not allow existing files to
be overwritten (except if 'mv' will query them).  It gives a running
commentary as it renames each file.

The job above becomes:
	
	rename 's/flip$/flop/' *.flip

More examples:

	rename 's/abc/xyz/g' *abc*
	rename 's/abc\(.*\)def/uvw\1xyz/' *
	rename 'y/abc/ABC/' *[abc]*

Enjoy,
	Geoff.

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	rename
# This archive created: Thu Feb  2 11:04:51 1989
echo shar: extracting rename '(897 characters)'
sed 's/^X//' << \SHAR_EOF > rename
X:
X#  rename.sh	Geoff Clare	Jan 1987
X
X#  Safely rename multiple files by applying a given 'sed' command
X#  to a list of file names
X
XUSAGE='Usage: rename sed_command file ...'
X
Xif test $# -lt 2
Xthen
X	echo >&2 "$USAGE"
X	exit 2
Xfi
X
X# Safeguards for existing files rely on 'mv' interactive behaviour
Xif test ! -t 0
Xthen
X	echo >&2 "rename: must be used interactively"
X	exit 2
Xfi
X
X# Dup standard input to use in 'mv' command
Xexec 3<&0
X
XCMD="$1"
Xshift
X
X# Let 'ls' spot non-existent files for us
X# The first 'p' command prints the old name on a line before the new name
X
X/bin/ls -d "$@" | /bin/sed -e p -e "$CMD" | while read old
Xdo
X	read new || new="$old"
X
X	if test "X$old" = "X$new"
X	then
X		echo >&2 "$old: no change"
X	elif test -w "$new"	# 'mv' will query non-writable files
X	then
X		echo >&2 "$old not renamed: $new already exists"
X	else
X		echo >&2 "$old --> $new"
X		/bin/mv 0<&3 "$old" "$new"
X	fi
Xdone
SHAR_EOF
if test 897 -ne "`wc -c rename`"
then
echo shar: error transmitting rename '(should have been 897 characters)'
fi
#	End of shell archive
exit 0
-- 

Geoff Clare    UniSoft Limited, Saunderson House, Hayne Street, London EC1A 9HH
gwc@root.co.uk   ...!mcvax!ukc!root44!gwc   +44-1-606-7799  FAX: +44-1-726-2750

jeff@softop.UUCP (Jeff) (02/04/89)

In article <626@jonlab.UUCP>, jon@jonlab.UUCP (Jon H. LaBadie) writes:
> <deleted stuff about doing this>> 
> An alternative, is one command line to create a list of "root names"
> and loop through them.  For a large number of files, this could
> greatly enhance the efficiency of the processing.  Ksh users could
> improve upon this even more using the special substitution facilities
> of that shell.
> 
> 	for root in `ls *.flip | cut -d. -f1`
> 	do
> 		mv ${root}.flip ${root}.flop
> 	done
> 

Gee guys, what about csh.  I was RTFMing today (yes, and I'll admit it on
network postnews) and found ... drum roll ... the :x modifiers.  Specifically,
:r gives you the root (i.e. no extension) of a symbol.

So, I assert (yes folks, no testing), that the following is just what the 
doctor ordered

	foreach file-to-be-renamed (*$flip)
		mv $file-to-be-renamed ${file-to-be-renamed:r}.$flop
	end

And now I wait for the howls of derision.
-- 

  ----------------------------------------------------------------------------
  | Jeff Tate              |     2425 Pandora Street, Vancouver, BC, Canada  |
  | van-bc!softop!jeff     |                                 (604) 254-4583  |
  ----------------------------------------------------------------------------

eiger@unigs.CH (Eiger Richard) (02/09/89)

A simple way to solve the often found problem of renaming some files
suffixes can be solved as follows (at least under UNIX V):

for name in *.flip
do
mv $name `basename $name .flip`.flop
done

which will rename all files *.flip in such with the extension .flop.
The command basename can be used for other tasks as well. Please check the
user's manual (1).

Best luck         Richard Eiger

mirk@warwick.UUCP (Mike Taylor) (02/09/89)

In article <626@jonlab.UUCP> jon@jonlab.UUCP (Jon H. LaBadie) writes:
>Randal and others (this is not intended to pick on Randal's suggestion)
>have proposed work-arounds to UNIX's command line interpreters (or to
>mv's) deficiency in wild card matching.
[He is referring to "wrong" behaviour of commands such as "mv *.flip *.flop"]

Hmmm, you'd like to blame this one on UNIX's wild-card handling, would
you?  Well, think about it.  In UNIX, the shell (whichever you choose
to use) does *all* wildcard expansion, and passed the result to
whatever commands are invoked.  There is, therefore, a single, well-
defined and well-understood patern of behaviour.  The alternative,
and this is what MSDOS does, is for each command to include its own
pattern-matching code, so that, firstly, the wheel is re-invented over
and over, and secondly, and IMHBDO much more seriously, different
commands may expand wildcards in different ways.

What you suggest is an example of this: The "*" in the mv(1) command
is required to act differently from that in, for instance, the command
"cp file1 file2 file3 dir", or "cp file* dir".  This sort of
incosistency, while it makes things more immediately intuitive for the
novice, means that there is no real understanding of how such things
will work in a general case - surely not a good state of affairs.

Sorry if this sounds like flamage, you do make some good points in
your article, (eg: that all the proposed solutions seem to involve
invoking a new process other than the mv(1)s themselves)  But it is
important to have consistency, and I think that UNIX's approach to
pattern matching is optimal.  Let's all remember Henry Spencer's
signature, shall we?

	"Those who do not understand UNIX are condemned to
	 re-invent it, poorly."
______________________________________________________________________________
Mike Taylor - {Christ,M{athemat,us}ic}ian ...  Email to: mirk@uk.ac.warwick.cs
Unkle Mirk sez: "You fritter and waste the hours in an offhand waistcoat." :-)
------------------------------------------------------------------------------