Arcady Genkin <[EMAIL PROTECTED]> writes:
> What would be the easiest way to rename a bunch of files
>
> foo-[0-9]-bar-[0-9][0-9].txt
>
> into
>
> blah-[0-9]-[0-9][0-9].txt
>
> Note, that all of the files have identical portions `foo-', `-bar-',
> and `.txt' in the filenames. Different are two numerical parts.
A low-tech bash-only way to do this is:
for n in foo-*-bar-*.txt; do nn=${n/-bar-/-}; mv $n ${nn/foo/blah}; done
I actually use this quite often when I need to replace only one part
of the name. Plus you get to preview your changes when you replace
`mv' by `echo' in a dry run.
This was for the `easiest way' part.
Complex replacements get tedious with this technique, though. If
you're feeling really brave and are the do-it-yourself kind of person,
you won't want to resort to mmv or something else that is designed for
the job. You use sed to assemble a stream of commands that you pipe
into a shell:
ls foo-*-bar-*.txt | sed 's/\(foo\(.*\)bar-\(.*\)\)/mv \1 blah\2\3;/' | sh
or so. For increased power/obfuscation, you could pipe the output of
find into sed. This enables you to rename files in a whole directory
tree, and move them through the filesystem in interesting ways
(flattening directory hierarchies, for instance). This makes for
beautiful sed patterns, because the `/'s need to be escaped in sed:
find -type f | sed -e h -e 's/\.\///' -e 'y/\//-/' -e x -e G \
-e 's/\n/ /' -e 's/\(.*\)/mv \1;/' | sh
would transform
foo.txt
for/bar.txt
a/very/very/long/path/and/then/some.more
into
foo.txt
for-bar.txt
a-very-very-long-path-and-then-some.more
leaving some empty directories behind.
Now if you choose not to quote the sed expressions, because you could
as well escape them, you get
find -type f | sed -e h -e s/\\.\\/// -e y/\\//-/ -e x -e G \
-e s/\\n/\ / -e s/\\\(.\*\\\)/mv\ \\1\;/ | sh
I think this has a certain ring to it. Of course, my sed expressions
might be overly complicated, as complete mastery of sed is not really
simple to attain for mere mortals.
Have fun,
Matthias