Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

rename with wildcards 3

Status
Not open for further replies.

RobBroekhuis

Technical User
Oct 15, 2001
1,971
US
OK, I know my way around Unix fairly well, but this one still stumps me. How do I rename with wildcards? For example, if I want to change any .JPG files to .jpg, this
doesn't work:

mv *.JPG *.jpg
(as an old DOS-head, that's what comes naturally).
So how do I do it? I can work around using cp and rm, but I have to believe there is a cleaner way?



Rob
[flowerface]
 
Nope! There isn't.

If you want to rename to lowercase you can thy the following:
Code:
for U in $*
do
  mv $U $(echo $U | tr "[:upper:]" "[:lower:]")
done

Theophilos.

-----------

There are only 10 kinds of people: Those who understand binary and those who don't.
 
Try something like this:
for f in *.JPG
do [ -f "$f" ] && mv "$f" `basename "$f" .JPG`.jpg
done

Hope This Help, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884
 
Or ...
[tt]
for file in *.JPG
do
mv $file ${file%JPG}jpg
done
[/tt]
 
Thanks for all the suggestions. Star to Ygor for the shortest approach. I had no idea you could do anything of the kind - I'll look up this construct and learn more when I have a few spare minutes.
Cheers


Rob
[flowerface]
 
Code:
rename JPG jpg *

rename might be a GNU utility; I'm not sure.
 
Also, to understand what your first try says, and why it can't work:

Pretend you're in a directory containing [tt]cat.JPG[/tt], [tt]dog.JPG[/tt], and [tt]pig.JPG[/tt].

When you say:
Code:
mv *.JPG *.jpg

it gets expanded to:
Code:
mv cat.JPG dog.JPG pig.JPG *.jpg
or
Code:
mv cat.JPG dog.JPG pig.JPG

Your shell performed wildcard expansion (also known as globbing).

It looked for all files whose name was something followed by [tt].JPG[/tt] and came up with three matches.

Then, it looked for all files whose name was something followed by [tt].jpg[/tt]. It, of course, found no such name, so it either assumed you meant a file named [tt]*.jpg[/tt] or allowed it to expand to nothing, depending on how it's set up to handle null globs.


So... [tt]mv[/tt] gets 3 or 4 arguments. If you look at the man page for [tt]mv[/tt], it'll tell you that whenever you give more than 2 arguments, the last one must be a directory, and all previous arguments will be moved into it. If the last argument is not an existing directory, it's an error.

Of course, that makes perfect sense. It's pretty much always going to be a mistake to try to rename a group of files to the same thing; you'd just end up deleting all the files except for one lucky one, which would get renamed to the last argument.


Thus, since neither [tt]pig.JPG[/tt] nor [tt]*.jpg[/tt] is an existing directory, the command you generate is an error.


Now, I don't know how DOS handles that kind of construct that you claim works. If it really does, here's an attempted explanation of why it does (and why it shouldn't).

First of all, the [tt]*.jpg[/tt] would somehow have to expand to a list of nonexistant filenames, probably based on the results of the previous glob on the same line. That'd be horrible hack #1. What happens if you wanted that second glob to expand to actual filenames? What controls how that list gets generated from the original? What happens if you have 3 globs per line? Horrible, horrible...

Second of all, the program doing the move operation would basically have to look at your arguments, check to see that they're an even number, and make the assumtion that you want to divide that list in half, then move each file in the first half to each file in the second half. So what happens when you try to move a bunch of stuff to a single directory, and you happen to have an even number of arguments? Do you move everything into that directory, or do you clobber the second half of the list with the first half? Horrible, horrible.


Ok, admittedly, I do know there's a separate DOS [tt]move[/tt] and [tt]rename[/tt] command, so that second point might not be as big a hack as I make it out to be. However, the first one is still valid, and the second should still give you some insight on why your original command can't work (in UNIX, anyway).


As a final example/warning, pretend you've only got [tt]cat.JPG[/tt] and [tt]dog.JPG[/tt], and pretend your shell is set up to expand [tt]*.jpg[/tt] into nothing when there are no matching files.

Code:
mv *.JPG *.jpg
expands to:
Code:
mv cat.JPG dog.JPG

and you now nove no pictures of a dog, and one picture of a cat named [tt]dog.jpg[/tt].


(Oh, and you may be amused to know that when I originally typed this, I meant to put [ignore][tt]cat.JPG[/tt][/ignore] to produce [tt]cat.JPG[/tt], but I accidentally typed [ignore][cat].JPG[/tt][/ignore], which happens to expand to [cat].JPG[/tt], so you would have gotten a funny-looking filename had I not thought to preview before submitting).
 
rename doesn't work in my environment. Thanks for the detailed explanation - I figured it was something like that, but admit I didn't understand the detailed inner workings of Unix command expansion.
Cheers


Rob
[flowerface]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top