Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

check to see if a file has todays data in it, if it has exit if not then add data

by john.tm (Scribe)
on May 30, 2014 at 00:32 UTC ( [id://1087903]=perlquestion: print w/replies, xml ) Need Help??

john.tm has asked for the wisdom of the Perl Monks concerning the following question:

i have a script that runs and updates a monthly csv file with data from a daily csv file what i am trying to add, is a check, that if the current days Date is in the file in column A then that means data has already been copied over from the daily file, so do nothing and exit. But if todays Date is not in column A then copy the data and append to the monthly file. what i have so far works until i try and append the data. then it always appends even if todays dat is present.
#!/usr/local/bin/perl #use warnings; use strict; use POSIX 'mktime'; use POSIX 'strftime'; my @dateParts = localtime (); my ($day, $month, $year) = @dateParts[3 .. 5]; $year += 1900; $month += 1; open (OUTPUT, '+<', "C:\\temp\\MONTHLY.CSV") or die "Cannot open file + $!\n"; while (defined (my $line = <OUTPUT>)) { chomp $line; my ($Date) = split ',', $line; if ($Date eq "$day $month $year") { close OUTPUT; exit print "\ file has already been updated today"; } elsif ($Date ne "$day $month $year") { # it works fine until i try this #open (INPUT, "C:\\temp\\DAILY.CSV") or die "Cannot open file $!\ +n"; #open (OUTPUT, '>>', "C:\\temp\\MONTHLY.CSV") or die "Cannot open + file $!\n"; #<INPUT>; #while (<INPUT>) { print OUTPUT; } }} #close INPUT; #close OUTPUT;
  • Comment on check to see if a file has todays data in it, if it has exit if not then add data
  • Download Code

Replies are listed 'Best First'.
Re: check to see if a file has todays data in it, if it has exit if not then add data
by boftx (Deacon) on May 30, 2014 at 01:00 UTC

    Disregarding a few other errors in that script (like, why did you comment out use warnings;?), I would suspect that the date format in your input file probably isn't as consistent as you think it is. Have you made a run where all you do is print the value of $Date to verify it will always match what you think it does?

    On a tangent, if you have control over the files, I suggest you use a more standard date format, such as YYYY-MM-DD, that is easily produced and parsed. You'll save yourself time and headaches down the road.

    It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re: check to see if a file has todays data in it, if it has exit if not then add data
by mr_mischief (Monsignor) on May 30, 2014 at 01:19 UTC

    You are testing for the date matching on every line. This is not what you want. I think what I've put together below gets you closer.

    #!/usr/local/bin/perl use warnings; use strict; use Fcntl (); my @dateParts = localtime (); my ($day, $month, $year) = @dateParts[3 .. 5]; $year += 1900; $month += 1; my $already_there = 0; open my $mon, '<', "C:\\temp\\MONTHLY.CSV" or die "Cannot read file $! +\n"; while ( defined ( my $line = <$mon> ) ) { my ( $date ) = split ',', $line; if ( $date eq "$day $month $year" ) { print "\ file has already been updated today"; $already_there++; last; } } close $mon; if ( ! $already_there ) { open my $day, "C:\\temp\\DAILY.CSV" or die "Cannot read file $!\n" +; flock $day, Fcntl::LOCK_SH; open $mon, '>>', "C:\\temp\\MONTHLY.CSV" or die "Cannot write to f +ile $!\n"; flock $mon, Fcntl::LOCK_EX; <$day>; # get past header while ( <$day> ) { print { $mon } $_; } close $day; close $mon or die "Could not complete writing to monthly file: $!\ +n"; } exit $already_there;
Re: check to see if a file has todays data in it, if it has exit if not then add data
by LanX (Saint) on May 30, 2014 at 00:54 UTC
    why don't you simply check the "last change time" of your file?

    > But if todays Date is not in column A then copy the data and append to the monthly file.

    Your script seems to check every single line in elsif if it doesn't have todays date, and of course there are lines which are older, hence you append.

    You'll need to check all lines (or better only the last one) first ALONE in one loop and AFTER this loop (if you haven't exited yet) you can append your data.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: check to see if a file has todays data in it, if it has exit if not then add data
by Anonymous Monk on May 30, 2014 at 01:03 UTC

    Well, whats all this mktime/strftime stuff, why aren't you using that? Why did you turn off the free help?

    Here is how I'd write it (minimize nesting loops)

    #!/usr/bin/perl -- ## ## 2014-05-29-18:05:27 ## ## perltidy -olq -csc -csci=10 -cscl="sub : BEGIN END if " -otr -opr +-ce -nibc -i=4 -pt=0 "-nsak=*" #!/usr/bin/perl -- use strict; use warnings; use POSIX qw/ strftime /; use Path::Tiny qw/ path /; #~ Main( @ARGV ); Main( 'C:/TEMP/DAILY.csv', 'C:/TEMP/MONTHLY.csv' ); exit( 0 ); sub Main { my( $infile, $outfile ) = @_; if( not has_today( $outfile ) ) { append_today( $infile, $outfile ); ... ## make noise on STDOUT } else { ... ## make noise on STDOUT } } ## end sub Main sub has_today { my( $infile ) = @_; my $today = strftime( '%Y %m %d', localtime ); my $fh = path( $infile )->open_raw; ... ## read last 8k, check for $today } ## assumes infile will fit in memory, if it don't, write more code :) sub append_today { my( $infile, $outfile ) = @_; path( $outfile )->append_raw( path( $infile )->slurp_raw ); }
    Path::Tiny, seek, readline
      when i try this i get Unimplemented at C:\testscripts\dir.pl line 31.
Re: check to see if a file has todays data in it, if it has exit if not then add data
by perlfan (Vicar) on May 30, 2014 at 12:27 UTC
    You could save yourself a lot of trouble if you store a field in the very top line that indicates the last date of a successful write - so you know exactly where to look each time.

    When you append, append to temp file and update the last write date. Then mv your temp file to be the new version of the file you're updating.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (4)
As of 2024-04-20 01:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found