Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

File::Find and replacing spaces in filenames.

by Kyshtynbai (Acolyte)
on Dec 22, 2012 at 16:56 UTC ( #1010031=perlquestion: print w/ replies, xml ) Need Help??
Kyshtynbai has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone!

I have to process a lot of filenames and directory names which may contain spaces: I want to change spaces with, lets say, _ symbol. I've googled for a solution; and I've found a rather ugly Bash string which however works fine.

I've decided to write a much more good-looking Perl script which would do the same thing. But the only code I was able to compose is the following code:

#!/usr/bin/perl use strict; use warnings; use File::Find; my $dir = "/home/ivan/M1"; find(\&wanted, $dir); sub wanted { my $file = $_; # storing unprocessed filename $_ =~ s/ /_/g; # replacing spaces with _ rename "$File::Find::dir/$file", "$File::Find::dir/$_"; # renaming + files }

I've run it; first time I've run it, it returned an error like this:

Can't cd to (/home/ivan/M1/) Some Dirname With Spaces: no such file or + directory at ./1.pl line 16

But it had processed all the filenames and changed spaces with _. I've run the script second time and it didn't return any mistake and all of my filenames and dirnames were processed.

My question is: what have I done wrong and how to improve this script? I'm a newbe in Perl and, to tell the truth, in Unix, so please don't blame me too hard :) . Thank you in advance.

Comment on File::Find and replacing spaces in filenames.
Select or Download Code
Re: File::Find and replacing spaces in filenames.
by Kenosis (Priest) on Dec 22, 2012 at 17:04 UTC
    • What happens when "my_file.txt" already exists and you encounter "my file.txt" (same issue with dir names)?
    • Consider just returning if no spaces found (no renaming necessary).
    • Will this renaming break anything that depends on previously-existing paths?

      1. Well, that is a problem. I'm going to think about it tonight.

      2. like this return 1 if $_ !~ /\s+/; ?

      3. No, it won't; files to process are just photos which are just stored on hdd, no software refers to them.

      Thanks!

        2. like this return 1 if $_ !~ /\s+/; ?

        No, because then you would have to perform a second match, which is unneeded. The s// operator returns the number of substitutions made, and 0 is perl's value for false.

        if ($_ =~ s/ /_/g) { # rename } else { return 1 }

        However, according to the docs for File::Find the return value of the wanted() function is ignored, so just write:

        if ($_ =~ s/ /_/g) { # rename }
Re: File::Find and replacing spaces in filenames.
by Anonymous Monk on Dec 22, 2012 at 19:11 UTC

    Your logic ends up like this:

    1. Enter directory
    2. Call wanted() sub, which renames the directory
    3. Return from the sub
    4. Get confused, since the directory we're in no longer exists

    You can make it work correctly if you only do the renaming after you've finished with the directory's children. File::Find provides the bydepth option to do that. (Or alternatively, the finddepth() subroutine)

      Thank you a lot! I should have read the description of the module more carefuly.
        I should have read the description of the module more carefuly.

        Amen brother, amen!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1010031]
Approved by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2014-07-26 14:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (177 votes), past polls