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

Dear Monks - thought i had succeded but today became stuck,
would you please be able to say how my line  (-f && '$_, !~ /^\./' &&  ($age > $limit))might be fixed to rename the files that do not begin with a dot?
atm. the script renames all files that are aged, ignoring dot prefix.
- thanks
Mark

my $limit = 20; find (\&CheckFile, "/Users/admin/Documents/ScriptTest/"); sub CheckFile { $File::Find::name; my $age = -M; if (-f && '$_, !~ /^\./' && ($age > $limit)) { rename ( $_, ".$_") or die "rename failed: $!"; } else { print $File::Find::name; print " is a youthfull ",int($age)," days old\n"; } }

Replies are listed 'Best First'.
Re: Rename old files that do not begin with a dot
by Corion (Patriarch) on Oct 27, 2008 at 19:51 UTC

    The code you posted doesn't make sense:

    What is the second line in this snippet supposed to do?

    sub CheckFile { $File::Find::name; my $age = -M;

    You could print out the filename, $age and what other inforamtion you find relevant.

    Also note that '$_, !~ /^\./' is a constant string, which likely is not what you meant. Maybe you meant

    $_ !~ /^\./

    instead? Also look at substr for an easy way of looking at the first character of a string.

Re: Rename old files that do not begin with a dot
by ikegami (Patriarch) on Oct 27, 2008 at 19:52 UTC
    if (-f && '$_, !~ /^\./' && ($age > $limit)) { ^^^^^^^^^^^^^^

    What's with the quotes? This is just a string literal. You might as well have written

    if (-f && 'Hello World' && ($age > $limit)) {

    Fix:

    if (-f && $_ !~ /^\./ && ($age > $limit)) {

    Or just

    if (-f && !/^\./ && ($age > $limit)) {

    Please wrap you code in <c>...</c> tags in the future.

Re: Rename old files that do not begin with a dot
by ikegami (Patriarch) on Oct 27, 2008 at 20:34 UTC

    Found a third bug. $_ isn't the variable you should be using. $_ is relative to some path relative under /Users/admin/Documents/ScriptTest/, but you're trying to rename a file in the current directory.

    • $File::Find::dir is the current directory name,
    • $_ is the current filename within that directory
    • $File::Find::name is the complete pathname to the file.
    my $limit = 20; find (\&CheckFile, "/Users/admin/Documents/ScriptTest/"); sub CheckFile { my $age = -M $File::Find::name; if ( -f $File::Find::name && !/^\./ && $age > $limit ) { rename ( "$File::Find::dir/$_", "$File::Find::dir/.$_") or die "rename failed: $!"; } else { print $File::Find::name; print " is a youthfull ", int($age)," days old\n"; } }
      Thank you so much for your help and advice,
      kind regards
      Mark
Re: Rename old files that do not begin with a dot
by runrig (Abbot) on Oct 27, 2008 at 19:53 UTC
    '$_, !~ /^\./' is a string that is always true. You could use parenthesis instead of the single quotes, if you took out the comma (why is the comma there?). But since you're matching against the $_ variable, you could replace the whole thing with !/^\./
Re: Rename old files that do not begin with a dot
by mr_mischief (Monsignor) on Oct 27, 2008 at 20:11 UTC
    You probably want <c> and </c> tags around your code for formatting and clarity.

    Have you tried taking the single quotes off of the '$_, !~ /^\./' part? Also, you shouldn't have a comma in that. So you'd have:

    if (-f && $_ !~ /^\./ && ($age > $limit)) {

    ... which you'd likely want to disambiguate for the programmer (perl has no problem) by using parentheses:

    if (-f && ($_ !~ /^\./) && ($age > $limit)) {

    ... and since pattern matches apply by default to $_ you could write as:

    if (-f && (! /^\./) && ($age > $limit)) {

    Yet you'd still have problems with files named, for example, 'foo' and '.foo', as you often can't rename one over the other and it will clobber the existing '.foo' with 'foo' if you can.