tags:

views:

799

answers:

6

I'm trying to create a process that renames all my filenames to Camel/Capital Case. The closest I have to getting there is this:

perl -i.bak -ple 's/\b([a-z])/\u$1/g;' *.txt # or similar .extension.

Which seems to create a backup file (which I'll remove when it's verified this does what I want); but instead of renaming the file, it renames the text inside of the file. Is there an easier way to do this? The theory is that I have several office documents in various formats, as I'm a bit anal-retentive, and would like them to look like this:

New Document.odt
Roffle.ogg
Etc.Etc
Bob Cat.flac
Cat Dog.avi

Is this possible with perl, or do I need to change to another language/combination of them?

Also, is there anyway to make this recursive, such that /foo/foo/documents has all files renamed, as does /foo/foo/documents/foo?

+9  A: 
Geo
http://search.cpan.org/dist/File-Find-Rule/lib/File/Find/Rule.pm is prettier than File::Find, but YMMV.
ephemient
I pretty much grew up using File::Find :). I like it more.
Geo
Global symbol "@directories" requires explicit package name at bob.pl line 5.Execution of bob.pl aborted due to compilation errors.Tried to run bob.pl(with latest edit) ^ is result.
ephemient
+3  A: 

Since Perl runs just fine on multiple platforms, let me warn you that FAT (and FAT32, etc) filesystems will ignore renames that only change the case of the file name. This is true under Windows and Linux and is probably true for other platforms that support the FAT filesystem.

Thus, in addition to Geo's answer, note that you may have to actually change the file name (by adding a character to the end, for example) and then change it back to the name you want with the correct case.

If you will only rename files on NTFS filesystems or only on ext2/3/4 filesystems (or other UNIX/Linux filesystems) then you probably don't need to worry about this. I don't know how the Mac OSX filesystem works, but since it is based on BSDs, I assume it will allow you to rename files by only changing the case of the name.

Eddie
Unlike the BSD filesystems, though, OS X's default HFS+ is case-insensitive. I don't have a Mac nearby to test whether case-only renames work...
ephemient
Andrew Medico
+1  A: 

I'd just use the find command to recur the subdirectories and mv to do the renaming, but still leverage Perl to get the renaming right.

find /foo/foo/documents -type f \
     -execdir bash -c 'mv "$0" \
                          "$(echo "$0" \
                              | perl -pe "s/\b([[:lower:]])/\u\$1/g; \
                                          s/\.(\w+)$/.\l\$1/;")"' \
              {} \;

Cryptic, but it works.

ashawley
StackOverflow doesn't allow comments with less than 10 chars. All I wanted to say is: +1,geek.
Geo
I'm embarrassed to have written it.
ashawley
+4  A: 

Most systems have the rename command ....

NAME rename - renames multiple files

SYNOPSIS rename [ -v ] [ -n ] [ -f ] perlexpr [ files ]

DESCRIPTION "rename" renames the filenames supplied according to the rule specified as the first argument. The perlexpr argument is a Perl expression which is expected to modify the $_ string in Perl for at least some of the filenames specified. If a given filename is not modified by the expression, it will not be renamed. If no filenames are given on the command line, filenames will be read via standard input.

   For example, to rename all files matching "*.bak" to strip the extension, you might say

           rename 's/\.bak$//' *.bak

   To translate uppercase names to lower, you’d use

           rename 'y/A-Z/a-z/' *

OPTIONS -v, --verbose Verbose: print names of files successfully renamed.

   -n, --no-act
           No Action: show what files would have been renamed.

   -f, --force
           Force: overwrite existing files.

AUTHOR Larry Wall

DIAGNOSTICS If you give an invalid Perl expression you’ll get a syntax error.

+1  A: 

Another one:

find . -type f -exec perl -e'
  map {
        ( $p, $n, $s ) = m|(.*/)([^/]*)(\.[^.]*)$|;
        $n =~ s/(\w+)/ucfirst($1)/ge;
        rename $_, $p . $n . $s;
      } @ARGV
  ' {} +
radoulov
A: 

Keep in mind that on case-remembering filesystems (FAT/NTFS), you'll need to rename the file to something else first, then to the case change. A direct rename from "etc.etc" to "Etc.Etc" will fail or be ignored, so you'll need to do two renames: "etc.etc" to "etc.etc~" then "etc.etc~" to "Etc.Etc", for example.

brianary