Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

use warnings; use File::Copy; use File::Find; find(\&rename_txts, "."); #Pfade ... find(\&rename_txts, "./txt2/"); sub rename_txts { if (/\.*$/) { my $new_name = $_; $new_name =~ y/ /-/; #Gives us the changed names: print "$File::Find::name to $new_name\n"; print "$_ \n"; #Try to exclude "." the current directory this is not working ... + elsif ($_ ne ".") { move $_, $new_name; } } }
The Elsif is not working i try to exclude the working directory "." from copying.
it is ok that the code is working "down" the directory tree that is a "feature"
Thx for any help

Replies are listed 'Best First'.
Re: elseif syntax error
by jakobi (Pilgrim) on Oct 27, 2009 at 14:18 UTC

    Please re-check your indenting and curlies ({,}). If the problem still isn't visually obvious for you, show us your current code again and tell us what if the elsif should come after. In contrast to C, Perl uses always the curlies in if () {...} elsif (...) {...} else {...}.

    cu & HTH, Peter -- hints may be untested unless stated otherwise; use with caution & understanding.
Re: elseif syntax error
by keszler (Priest) on Oct 27, 2009 at 14:29 UTC
    Your regex /\.*$/ will always match: it's looking for zero or more '.' characters at the end of the string. If you're attempting to eliminate the '.' and '..' directories you want:

    if (!/^\.+$/) {

    (String from start to end contains one or more '.' characters only)

      I think perhaps you meant

      if (!/^\.{1,2}$/) {
      or
      if (!/^\.\.?$/) {
      unless you're trying to avoid all entries that consist only of dots. ("...." is a valid name)

        Confused.

        Inspiration:

        $ echo 'wtf' > ... $ ls -l ... -rw-r--r-- 1 me me 4 Oct 27 10:50 ... $ cat ... wtf $

        Enlightened.

      Can't cd to (./test/) test test test test: No such file or directory at e:\path\myfiles\perl\filename_spaces2.pl line 7

      The code is fine it is not completely "recursive" someone of you got some hint how to go down in every subdirectory? If i start it a second time it is working ... On first attempt the directory tree is (i got several space containing files below E:\temp:

      #Perl should find spaces and replace them with "-" # use warnings; use File::Copy; use File::Find; find(\&rename_txts, "."); #Pfade ... find(\&rename_txts, "./txt2/"); sub rename_txts { if (!/^\.+$/) { my $new_name = $_; $new_name =~ y/ /-/; print "$File::Find::name to $new_name\n"; print "$_ \n"; move $_, $new_name; } }
      The result is:
      "E:\temp\test\test test test test"\Files with spaces ...
      2nd attempt:
      "E:\temp\test\test-test-test-test"Files-with-spaces...
      so the 2nd (or depending on the number of subdirectories run is ok)
      Thx for all your help so far
      btw: The purpose is to rename all the files on a network drive to proper names without spaces ...

        You don't need recursion, because the "find" function is traversing the directory structure for you.

        The errors you see are due to renaming of a directory before it is finished being used. Try "finddepth" instead of "find". The "finddepth" routine will process a directory's contents before the directory itself.

Re: elseif syntax error
by GrandFather (Saint) on Oct 28, 2009 at 00:24 UTC

    I find it helps clean up code a lot to use early exits. Consider using:

    sub someSub { if (some condition) { ... return; } if (some other condition) { ... return; } }

    instead of:

    sub someSub { if (some condition) { ... } elsif (some other condition) { ... } }

    Despite taking a few more lines the first version makes it much clearer what the conditions are for some task to be performed and makes the exit conditions much clearer. This technique can often collapse deeply nested conditional code to a single level.

    The same technique can be applied in loops to take early leave of the current iteration (using next) or terminate the loop early (using last).


    True laziness is hard work
      But if you use multiple if both blocks can be executed, and in case of using "elsif" construction only one block is executed. Or not? :)

        Look again. Not if you use an early exit at the end of each block.

        The whole point of the technique is to use an early exit at the end of each block to avoid the need to nest blocks and allow else blocks to turn into a simple unindented block of code.


        True laziness is hard work
Re: elseif syntax error
by biohisham (Priest) on Oct 27, 2009 at 14:38 UTC
    You haven't closed the block before starting the "elsif(){}", your code skeleton in the subroutine should've probably looked like the following pseudo:
    sub rename_texts{ if(){ }elsif(){ } }
    Consider perltidy for proper indentation, here is an introduction


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
      I think I'd prefer
      sub rename_texts{ if(){ } elsif(){ } }