Have you ever wanted to do something like
$ mv a.htm a.html
$ mv b.htm b.html
...
$ mv z.htm z.html
or
$ mv 030101.txt data_20030101.txt
$ mv 030102.txt data_20030102.txt
...
$ mv 031231.txt data_20031231.txt
which should be easy if you could use regular expressions?
pmmv makes your life easier using perl regular expressions. The above
examples are done simply by
$ pmmv 's/\.htm$/.html/'
$ pmmv 's/(\d{6})/data_20$1/'
Save pmmv in some appropriate directory, make it
executable by "chmod u+x pmmv", and enjoy!
You may need to change the first line
#!/usr/bin/perl
appropriately. To locate your perl, do "which perl".
Although I assume some knowledge of regular expressions, it should be
easy to adapt the examples below for your purpose. One can normally
read the manual of perl regular expressions by typing "man perlre".
- Replace words: foo → bar
$ pmmv s/foo/bar/
This replaces the first occurrence of foo in the filename with
bar. If you want to replace every foo in the filename with
bar, use
$ pmmv s/foo/bar/g
instead. The option g means "replace globally, i.e., all occurrences."
- Change extension: *.htm → *.html
$ pmmv s/\\.htm\$/.html/
$ pmmv 's/\.htm$/.html/'
These change the extension .htm into .html . The perl
s/// expression we want give to pmmv is
s/\.htm$/.html/ in both cases, but because
arguments are subject to shell parameter expansion, we need to escape
characters such as \ or $ by preceding backslashes.
By enclosing the perl s/// expression with single quotes,
almost all this complication can be avoided. (Unless we want single
quotes in the perl s/// expression. This is possible in
zsh by settin the
RC_QUOTES option.)
If we want to make this example case insensitive (namely, both
foo.htm and foo.HTM be moved to foo.html),
one can use
$ pmmv 's/\.htm$/.html/i'
The option i means "Do case-insensitive pattern matching."
- Switch word positions: "Fall 2003.doc" → "2003 Fall.doc"
$ pmmv 's/(\w+)\W+(\w+)\.doc/$2 $1.doc/'
This is the first example with backreference.
- Change date format: mmddyy → mmddyyyy: (e.g. "101303" →
"10132003")
$ pmmv 's/(\d{4})03/${1}2003/'
One needs to enclose the backreference variable name $1 with {}
in this example. This doesn't work for year 2004, obviously.
- Change date format: mm-dd-yy → mm-dd-yyyy: (e.g. "10-13-03" →
"10-13-2003")
$ pmmv 's/(\d{2})-(\d{2})-0(\d)/$1-$2-200$3/'
This is a little more complicated than the last example.
- Uppercase: abc → ABC
$ pmmv 's/(.)/uc($1)/ge'
This uppercases every alphabet letter. This is the first example with the
e option, which means "Evaluate the right side as an
expression." This option is very useful because one can make use
of the powerful perl functions. In this case, uc() is a
perl function that uppercases its argument.
- Fill with zeros: 1 → 001, 12 → 012
$ pmmv 's/(\d+)/substr("00".$1,-3)/e'
- Increase numbers: data1 → data2,
data2 → data3
$ pmmv -rs 's/(\d+)/$1+1/eg'
This will add one to every number in the filename. Namely,
data1.txt becomes data2.txt and 2003-10-11
becomes 2004-11-12. The -rs option sorts the files in
reverse alphabetical order before moving. This is necessary because
without -rs, pmmv would do
$ mv data1.txt data2.txt
$ mv data2.txt data3.txt
...
$ mv data9.txt data10.txt
Then all files would be gone except for data10.txt ! Anyway,
it is always a good idea to check if the expected outcome will result by
using the -c option first.
- Change date format: mmddyy → mmm-dd-yyyy (e.g. 123103 → Dec-31-2003)
$ pmmv 's/(\d{2})(\d{2})(\d{2})/[Jan, Feb,Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]->[$1-1]."-".$2."-".($3>30 ? 19 : 20).$3/e'
The following does the reverse:
$ pmmv 's/([A-z]+)-(\d{2})-(\d{4})/{Jan=>"01", Feb=>"02", Mar=>"03", Apr=>"04", May=>"05", Jun=>"06", Jul=>"07", Aug=>"08", Sep=>"09", Oct=>"10", Nov=>"11"}->{$1}."-".$2."-".substr($3,-2)/e'