Renaming Files
A quickie today, renaming a bunch of files in the shell. Unix gives you million ways to do it, here are a few that will help you understand your tools better.
The word has come down, Uber is the new Awesome and our files must reflect this (management is behind the curve, but they pay the bills).
Bash
With Bash we can take advantage of it’s Substring Replacement. The
format is ${variable/old_string/new_string}
and does what you’d image.
for f in *awesome*
do
mv $f ${f/awesome/uber}
done
tcsh
Personally, I find tcsh’s foreach loop format cleaner:
foreach f ( *awesome* )
mv $f `echo $f | sed s/awesome/uber/`
end
However tcsh doesn’t have variable substitution, so we end up invoking
sed to get the new name. Backticks
are key here, echoing the filename into sed
causing it to output
the name with the substitution. The backticks capture that output and
make it an argument to mv
.
find | xargs
find . -name '*awesome*' | sed 'p;s/awesome/uber/' | xargs -n2 mv
This as the advantage of searching through subdirectories. find
prints all file (or directories) containing the awesome in the
name. sed
has two commands p which just prints the original file
name and then the s substitution. We end up with a list that looks
like:
./one_awesome.c
./one_uber.c
./two_awesome_door.txt
./two_uber_door.txt
The -n2
option to xargs
says “process the input two entries at a
time” and mv
is the command to apply to those entries. In effect
this generates:
mv ./one_awesome.c ./one_uber.c
mv ./two_awesome_door.txt ./two_uber_door.txt
find
can also be used in the for loops to handle files in subdirectories.
for f in `find . -name '*awesome*'`
foreach f ( `find . -name '*awesome*'` )
The backticks captures find’s output and inserts it as the files list for the loop.
rename
Last, possibly easiest, and most confusing is rename
. Rename is a
problem because there are two different things called rename. One,
typically found RHEL type systems takes three arguments, the original
string, the new string and the filenames:
rename awesome uber *awesome*
Then there is the other, typically found on Debian/Ubuntu which takes a Perl expression.
rename s/awesome/uber/ *awesome*
If you do have rename
and you know which rename
you have, it doesn’t
get much simpler. The Mac doesn’t ship with either, though it’s easy
enough to install one.
One problem, four approaches. More importantly, a bunch of techniques that you can reach for when you need to manipulate a collection of files.
Comments