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

Hi Folks.

Say I have the following filenames :
# MON.DOC # TUE.DOC # WED.DOC
And i want to change them according to a variable, say, the current date. So I do
$mon = "MON.DOC"; $date = system ("date \'+%m%d%Y\'");
To get the current date. If I want $mon to change to MON_02082001.DOC, what do i do next???
$mon_$date;
doesn't seem to work :(

Thanks

cheers,
rass

Replies are listed 'Best First'.
Re: Creating Filenames using variables
by davorg (Chancellor) on Feb 08, 2001 at 16:31 UTC

    There's really no need to use date to get the date information - it's slower and you're introducing platform dependencies for no good reason.

    You can do it with Perl built-ins like this:

    my ($d, $m, $y) = (localtime)[3 .. 5]; ++$m; $y += 1900; $date = "$m$d$y";

    or, if that looks a little complex, use POSIX::strftime like this:

    use POSIX 'strftime'; $date = strftime('%m%d%y', localtime);

    You might also consider using a different naming scheme. Dates in the form MMDDYYYY are illogical and will confuse non-Americans. Why not use the ISO standard of YYYY-MM-DD?

    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

Re: Creating Filenames using variables
by OeufMayo (Curate) on Feb 08, 2001 at 16:24 UTC

    On a side note, you may also want to use localtime instead of system as it is less resource expensive.

    @d = qw[MON TUE WED THU FRI SAT SUN]; @t = localtime; $t[4]++; $t[5] += 1900; open(DOC, "> $d[$t[6]]_$t[3]$t[4]$t[5].doc") or die $!;
    ( you also have to play with sprinf, but I'm too lazy for that right now) <kbd>--
    PerlMonger::Paris(http => 'paris.pm.org');</kbd>
Re: Creating Filenames using variables
by mirod (Canon) on Feb 08, 2001 at 16:20 UTC

    The '_' is a valid character for a variable name, hence Perl looks for $mon_ and doesn''t find it (use strict will tell you that).

    You can use $mon . '_' . $date, or $mon . "_$date" or my favorite: "$mon\_$date"

    Update: of course you should do this only after performing the magnus manoeuver.

      mirod wrote:

      The '_' is a valid character for a variable name, hence Perl looks for $mon_ and doesn''t find it

      You can also get around this by being a little more explicit in identifying $mon, like so:

      print "${mon}_$date";

      That way, perl knows precisely which var you want.

      I use this whenever my data structs start getting complicated, kind of like using extra parentheses in an expression to make yourself clear.

      Whether or not that should serve notice that my data structures are too crufty and I should rethink my design is left as an exercise for the Meditations section. :-)

      Peace,
      -McD

Re: Creating Filenames using variables
by zigster (Hermit) on Feb 08, 2001 at 16:15 UTC
    Use '.' string concatination
    $filename = $mon . "_" . $date;
    HTH
    Update To be honest tho you would probs be best off using shell, checkout rename(1) if you are using linux you may find it easier.
    --

    Zigster
      Zigster that would get you MON.DOC_$date

      rass, you can try this... i just did and it works... careful of the trailing  \n on the date...
      $mon = "MON.DOC"; @name = split (/\./,$mon); $date = `date`; #(or whatever) $filename = $name[0] . "_" . $date . "." . $name[1];


      magnus
        Dowt, more hast less speed required on my part next time.. Thanks for the correction you are of course quite correct.
        --

        Zigster
        Nice catch magnus (and now you have your own manoeuver ;-), but I just wanted to point out the potential problem of filenames with multiple dots. There are plenty even on this Win32 box.

        --
        I'd like to be able to assign to an luser

Re: Creating Filenames using variables
by the_slycer (Chaplain) on Feb 08, 2001 at 21:03 UTC
    I kind of like the below, as it gets past the multiple dots in a file name (like test.doc.doc):
    #!/usr/bin/perl -w use strict; my @files=qw(blah.doc.doc blah.doc.txt blah.doc); my ($d, $m, $y) = (localtime)[3 .. 5]; ++$m; $y += 1900; my $date = "$m$d$y"; foreach (@files){ s/(.*)(\..*)/$1_$date$2/; print "$_\n"; }
Re: Creating Filenames using variables
by stefan k (Curate) on Feb 08, 2001 at 18:38 UTC
    Howdy,
    another solution for your date-system-call would be to use

    $date = qx/date +'%d.%m.%Y (%H:%M:%S)'/;

    But nowadays I'd prefer the use of strftime (like davorg posted) because it's more within perl (I like avoiding systemcalls whenever I know another way)

    Regards
    Stefan K

    $dom = "skamphausen.de"; ## May The Open Source Be With You! $Mail = "mail@$dom; $Url = "http://www.$dom";
Re: Creating Filenames using variables
by Boldra (Curate) on Feb 08, 2001 at 18:56 UTC
    You might also be interested in using perl's wonderful glob features. They allow you to do nice things like:
    foreach $old_name (glob("*.DOC")) { my $new_name = &add_date($filename); rename($old_name,$new_name); }
    This executes the foreach loop for each value of $old_name where $old_name is a filename matching "*.DOC". Note that you need to be in the correct directory to get the matches.

    &add_date would include the other chunks of code that other respondants have kindly written for you.

    eg.
    sub add_date { return s/\.DOC/time().".DOC"/e; }

    (which I haven't tested)
Re: Creating Filenames using variables
by Vystrax (Initiate) on Feb 08, 2001 at 21:41 UTC
    Alternative to using regex which still handles multiple ".":
    $mon = '/accounts/person/code.42/file.MON.DOC'; my ( $d, $m, $y ) = (localtime)[3..5]; ++$m; $y+=1900; substr($mon,rindex($mon,'.'),0)=".$y$m$d";
Re: Creating Filenames using variables
by Pahrohfit (Sexton) on Feb 08, 2001 at 23:52 UTC
    Try a little something like this:
    $mon =~ s/(.+)(\..+)/$1_`date \+\%m\%d\%Y`\.$2/e;
    Update : /e added to end of regex to fix error. (Thanks to EvanK)
      good idea including the date process in the regex. still forgot the /e regex flag though, and the original post used system, not backquotes

      ______________________________________________
      When I get a little money, I buy books. If I have any left over, I buy food and clothes.
      -Erasmus

Re: Creating Filenames using variables
by EvanK (Chaplain) on Feb 08, 2001 at 23:44 UTC
    well, as the others said about the underscore being interpreted, you'd have to seperate it with the . operator or escape it, and if you want the date after MON but before .DOC ala magnus' observation, heres a quicker, one line solution...regexes to the rescue. >:-]~
    $mon =~ s/(.+)\.(.+)/$1\_$date\.$2/;

    ______________________________________________
    When I get a little money, I buy books. If I have any left over, I buy food and clothes.
    -Erasmus

Re: Creating Filenames using variables
by timbu (Novice) on Feb 09, 2001 at 03:25 UTC

    Instead of using $mon_$date how about this?

    my $newFilename = $date; $newFilename .= "_"; $newFilename .= $month;

    I know it's extra lines of code but is easy to read. I have always like concatenating with '.='. Try it you'll like it.

Re: Creating Filenames using variables
by Anonymous Monk on Feb 09, 2001 at 00:45 UTC
    See Conacatination or Join command
Re: Creating Filenames using variables
by Anonymous Monk on Feb 09, 2001 at 11:34 UTC
    Try: $date = qx\date "+%m%d%Y"\; it seems to work for me. cheers, Bobbydon
Re: Creating Filenames using variables
by Anonymous Monk on Feb 09, 2001 at 05:58 UTC
    # original file name :
    $mon = "MON.DOC";

    # split name into it's 3 letter day name and the extension
    # each part will go in $1 & $2 by default :
    $mon =~ /^(\w{3})(\.DOC)/;

    # save parts in appropiately named variables :
    ($day, $ext) = ($1, $2);

    # the following code will run the 'date' command and print the output to STDOUT
    # however, the return value of the sub 'system' is the exit value of the 'date'
    # command execution, which is usually 0 for success, therefore $date would be
    # equal to 0 (zero) :
    # $date = system ("date \'+%m%d%Y\'");

    # what you want to do instead is run the 'date' command with backticks instead
    # of 'system'.
    # this way, the output of 'date' is not printed to STDOUT, but rather returned
    # and stored into $date.
    # chomp is necessary to remove the newline character :
    chomp($date = `date '+%m%d%Y'`);

    # To get the current date. If I want $mon to change to MON_02082001.DOC, what do i do next???

    $mon = $day . '_' . $date . $ext;
    print $mon;

    # the output should be as follows :
    # MON_02082001.DOC

    by coralyn
    e-mail: coralyn@ILoveJesus.net
    fly.to/ChiAlpha

Re: Creating Filenames using variables
by Anonymous Monk on Feb 09, 2001 at 05:53 UTC
    # original file name :
    $mon = "MON.DOC";

    # split name into it's 3 letter day name and the extension
    # each part will go in $1 & $2 by default :
    $mon =~ /^(\w{3})(\.DOC)/;

    # save parts in appropiately named variables :
    ($day, $ext) = ($1, $2);

    # the following code will run the 'date' command and print the output to STDOUT
    # however, the return value of the sub 'system' is the exit value of the 'date'
    # command execution, which is usually 0 for success, therefore $date would be
    # equal to 0 (zero) :
    # $date = system ("date \'+%m%d%Y\'");

    # what you want to do instead is run the 'date' command with backticks instead
    # of 'system'.
    # this way, the output of 'date' is not printed to STDOUT, but rather returned
    # and stored into $date.
    # chomp is necessary to remove the newline character :
    chomp($date = `date '+%m%d%Y'`);

    # To get the current date. If I want $mon to change to MON_02082001.DOC, what do i do next???

    $mon = $day . '_' . $date . $ext;
    print $mon;

    # the output should be as follows :
    # MON_02082001.DOC