|
|
|
|
|
|
|
|
How do I rename "*.foo" to "*.bar", or change file names to lowercase?
|
|
O.k., you have a a bunch of files that have "*.foo" file extention, and
you need to rename all of them to "*.boo." Thus you try "mv *.foo *.bar"
at command prompt. However, as you already know by now, that would not work.
Why doesn't "mv *.foo *.bar" work? Think about how the shell
expands wildcards. "*.foo" and "*.bar" are expanded before the
mv command ever sees the arguments. Depending on your shell,
this can fail in a couple of ways. Csh (=C shell) prints "No match."
because it can't match "*.bar". Sh (=Bourne Shell) executes "mv a.foo b.foo
c.foo *.bar", which will only succeed if you happen to have a
single directory named "*.bar", which is very unlikely and almost
certainly not what you had in mind.
Depending on your shell, you can do it with a loop to "mv" each
file individually. If your system has "basename", you can use:
C Shell:
-
foreach f ( *.foo )
set base=`basename $f .foo`
mv $f $base.bar
end
Bourne Shell:
-
for f in *.foo; do
base=`basename $f .foo`
mv $f $base.bar
done
Some shells have their own variable substitution features, so
instead of using "basename", you can use simpler loops like:
C Shell:
-
foreach f ( *.foo )
mv $f $f:r.bar
end
Korn Shell:
-
for f in *.foo; do
mv $f ${f%foo}bar
done
If you don't have "basename" or want to do something like
renaming foo.* to bar.*, you can use something like "sed" to
strip apart the original file name in other ways, but the general
looping idea is the same. You can also convert file names into
"mv" commands with 'sed', and hand the commands off to "sh" for
execution. Try
-
$ ls -d *.foo | sed -e 's/.*/mv & &/' -e 's/foo$/bar/' | sh
Shell loops like the above can also be used to translate file
names from upper to lower case or vice versa. You could use
something like this to rename uppercase files to lowercase:
C Shell:
-
foreach f ( * )
mv $f `echo $f | tr '[A-Z]' '[a-z]'`
end
Bourne Shell:
-
for f in *; do
mv $f `echo $f | tr '[A-Z]' '[a-z]'`
done
Korn Shell:
-
typeset -l l
for f in *; do
l="$f"
mv $f $l
done
If you wanted to be really thorough and handle files with `funny'
names (embedded blanks or whatever) you'd need to use
Bourne Shell:
-
for f in *; do
g=`expr "xxx$f" : 'xxx\(.*\)' | tr '[A-Z]' '[a-z]'`
mv "$f" "$g"
done
The `expr' command will always print the filename, even if it
equals `-n' or if it contains a System V escape sequence like `\c'.
Some versions of "tr" require the [ and ], some don't. It
happens to be harmless to include them in this particular
example; versions of tr that don't want the [] will conveniently
think they are supposed to translate '[' to '[' and ']' to ']'.
|
|
|