LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   search a date range in perl (https://www.linuxquestions.org/questions/programming-9/search-a-date-range-in-perl-4175652762/)

vinmansbrew 04-25-2019 10:07 AM

search a date range in perl
 
So, disclaimer, I know zilch about perl. The script I have to use was originally written in perl. So, bear with me as I completely use the wrong terms!

I need to take a working script, but modify it to search starting at a certain date to today. Hours don't matter, just day/month/year. For example, starting march 10 2019 to today.

How would I do this?

Thanks!

btw, the script is running on rhel 6.10

TB0ne 04-25-2019 10:17 AM

Quote:

Originally Posted by vinmansbrew (Post 5988433)
So, disclaimer, I know zilch about perl. The script I have to use was originally written in perl. So, bear with me as I completely use the wrong terms!

I need to take a working script, but modify it to search starting at a certain date to today. Hours don't matter, just day/month/year. For example, starting march 10 2019 to today. How would I do this?

Thanks! btw, the script is running on rhel 6.10

Perl has a TON of date/time processing modules. Since you don't post ANY of the script, it's hard to see what you have to work with. Time::Piece is a great module, but the Date::Simple or Date::Time also provide a good interface. You don't say where you're getting the date from (user input? File? File date?), in what format, or what you're searching with that date or how.

If it was me, and I was getting a date from a user, I'd force a format of YYYY-MM-DD, and convert it to epoch time, and just get the date now in epoch time, and do the search. Again, you don't say what you're searching...a TIMESTAMP field in MySQL takes something different. Running a Linux 'find' command also needs something different.

Short answer: you have lots of options which are easy to implement, but they're going to depend on where you get the input data, and how you use it.

vinmansbrew 04-25-2019 10:25 AM

Here is the script, as it currently is:

Code:

#!/usr/bin/perl -w

use strict;
use Net::LDAP;
use Time::Piece;

if ($#ARGV < 0)
{
  print STDERR "Usage: ./newstudents.pl pwd\n";
  exit 1;
}

my $host = "cobber";
my $bindcred = $ARGV[0];
my $binddn = "cn=Directory Manager";
my $basedn = "ou=People,dc=test,dc=com";
my $dateout = Time::Piece->new->strftime('%Y%m%d');
my $infile = "output/$dateout/newstudents.list";

open(OUTFILE, ">", $infile) or die("Can't open $infile.clean for output");

my $ldap = Net::LDAP->new($host, timeout=>2) ||
  SYSerror("New", "Couldn't connect to $host");
my $mesg = $ldap->bind("$binddn", password=>"$bindcred");
if ($mesg->is_error) {LDAPerror("Bind", $mesg);}

my $result = $ldap->search(base=>"$basedn", scope=>"sub",
  filter=>"(&(!(nsAccountLock=*))(BannerRole=APPLICANTACCEPT))",
  attrs=>["mail","cn"]);
if ($result->is_error) {LDAPerror("Search", $result);}

my @entries = $result->entries;


my $mExcludingFile = "excludes/new-students.txt";
my $includingFile = "includes/new-students.txt";
my @mArray = ();
my $mLine;
my $mCountAll = 0;
my $mCountOrig = 0;
my $mCountAdd = 0;
my $mCountDel = 0;

open(ROFILE, "<", $mExcludingFile) or die("Can't open $mExcludingFile exception file!");
while(<ROFILE>) {
  push(@mArray, $_);
}
close(ROFILE);

my $mArrayNow;
my $entry;

foreach $entry(@entries) {
      my $name = $entry->get_value("cn");
      my $email = $entry->get_value("mail");
      my $mLineNow = "$email $name\n";
      my $mOkay = 1;
      $mCountOrig++;

      foreach $mArrayNow (@mArray) {
        if ($mLineNow eq $mArrayNow) {
          $mOkay = 0;
        }

      }

      if ($mOkay == 1) {
        print OUTFILE $mLineNow;
      } else {
                $mCountDel++;
      }
}

flock(OUTFILE, 8);
close(OUTFILE);
open(OUTFILE, ">>", $infile);
open(EXCEPTF, "<", $includingFile) or die("Can't open $includingFile exception file!");
while(<EXCEPTF>) {
        print OUTFILE $_;
        $mCountAdd++;
}
flock(OUTFILE, 8);
close(OUTFILE);
close(EXCEPTF);


$mCountAll = $mCountOrig + $mCountAdd - $mCountDel;

print "Ok.. Generated ".$mCountAll." (".$mCountOrig." + ".$mCountAdd. " - ".$mCountDel.")\n";

sub LDAPerror
{
  my ($from, $mesg) = @_;
  print "Error: " . $mesg->code . " (" . $mesg->error_name . ")\n";
  print $mesg->error_text . "\n";
}

sub SYSerror
{
  my ($from, $mesg) = @_;
  print "Error: $mesg\n";
  print "Source: $from\n";
  die "$@";
}

Ok, so I tried to preserve the format.

Essentially what is happening is the script uses an ldap connection to a banner database, which then creates a text file with a list of names/emails used for updating a listserv.

pan64 04-25-2019 12:46 PM

thanks. Would be nice to use [code] tags to keep original formatting.
I have no any idea what are you (the script) searching for and especially what to do (what should be compared) with that time.

astrogeek 04-25-2019 01:19 PM

To preserve formatting place your code snippets inside [CODE]...[/CODE] tags. You may type those yourself or click the "#" button in the edit controls.

There are no clues in your original question or the posted code as to what date you want to search for.

Is it the timestamp of some files, or the content of some files, or lines in one file... we cannot tell from what you have posted.

Please review the Site FAQ for guidance in posting your questions and general forum usage. Especially, read the link in that page, How To Ask Questions The Smart Way. The more effort you put into understanding your problem and framing your questions, the better others can help!

TB0ne 04-25-2019 01:19 PM

So you're using Time::Piece and getting the current date for the report. Fine....so that gives you your 'date now'. And it looks like you're trying to look up someone in LDAP, and creating files, reading from other files, etc. But since we have NONE of those, we can't even run the code you've posted. And again, as asked, where is the date going to be coming FROM?? Is the user going to enter it/be prompted for it?? What is the actual GOAL of this script having a date-range and where is the date in what you're searching???

Nothing you've describe is particularly hard, and the fact you've already got the date module in, running, and getting one of the two dates means you're a good part of the way there.

vinmansbrew 04-25-2019 02:14 PM

Ok, I have tried to preserve the format. I explained a bit more also in the same post. As for the time part, I want to be able to limit the time for results to filter out old results. I hope I have given helpful info.

TB0ne 04-25-2019 02:36 PM

Quote:

Originally Posted by vinmansbrew (Post 5988490)
Ok, I have tried to preserve the format.

Yes..after posting it with no formatting the first time.
Quote:

I explained a bit more also in the same post. As for the time part, I want to be able to limit the time for results to filter out old results. I hope I have given helpful info.
Still haven't answered anything that was asked. AGAIN:
  • How is the beginning of the date-range getting into the program?? User entered/file/what????
  • What is actually being searched? We can GUESS as to an LDAP query, but where is the date in the LDAP query??
  • We have NONE of the ancillary files specified in your program (include/exclude/etc.)...what is in those?
  • What is the ACTUAL GOAL of this program??? What are you trying to do, against what data set?
Just saying "I need to do a date range search" tells us next to nothing. Again, you've got a date/time module that's pretty robust already in your code. You're already getting todays date, giving you 50% of what you're after.

scasey 04-25-2019 02:39 PM

Quote:

Originally Posted by vinmansbrew (Post 5988490)
Ok, I have tried to preserve the format. I explained a bit more also in the same post. As for the time part, I want to be able to limit the time for results to filter out old results. I hope I have given helpful info.

Thanks for using the [code] tags.
As has been asked, where is the other date coming from?
What do you mean by "old results"?
How will you filter them out?

vinmansbrew 04-25-2019 02:58 PM

I am basically just trying to set a date range. It is currently taking everything up to today. What I want to do is to limit how far back it goes, i.e. 03/12/2019 to today.
A lot of the other info I just do not have since I have no access of the banner database, I can say people are entered in by "roles" such as staff, admin, ect. The ldap portion isn't really important is the script is just using it to access the db. The db compiles the list, which is then just outputted to a txt file.

TB0ne 04-25-2019 03:03 PM

Quote:

Originally Posted by vinmansbrew (Post 5988504)
I am basically just trying to set a date range. It is currently taking everything up to today. What I want to do is to limit how far back it goes, i.e. 03/12/2019 to today.

Yes..you've said this numerous times now. What you STILL haven't told us is WHERE the start date is going to come from????? AGAIN, are you wanting the user to input it on the command line, do are you running this through a GUI of some sort, web page, what????
Quote:

A lot of the other info I just do not have since I have no access of the banner database, I can say people are entered in by "roles" such as staff, admin, ect. The ldap portion isn't really important is the script is just using it to access the db. The db compiles the list, which is then just outputted to a txt file.
...and back to "what is it querying"???

If you don't have the answers, we sure won't either. Just restating what you want to do over and over is pointless. If you don't know about Perl, how/why did you get handed this script and told to modify it? Who wrote this script to start with?

scasey 04-25-2019 03:06 PM

Quote:

Originally Posted by vinmansbrew (Post 5988504)
I am basically just trying to set a date range. It is currently taking everything up to today. What I want to do is to limit how far back it goes, i.e. 03/12/2019 to today.
A lot of the other info I just do not have since I have no access of the banner database, I can say people are entered in by "roles" such as staff, admin, ect. The ldap portion isn't really important is the script is just using it to access the db. The db compiles the list, which is then just outputted to a txt file.

Is the start date always going to be 3/12/2019?
Set a variable to the starting date. Use the same syntax as for the $dateout variable.
That is the beginning of your range.

As has been said, you're not giving us anything at all to work with to help you. I can't see any place dates are used in that script except to define the location of a file.

vinmansbrew 04-25-2019 03:48 PM

The start date was arbitrary, I just picked that date.
Would I put the $dateout variable before or after the current $dateout variable?

I was given this mainly cause I drew the short straw. No one here does perl anymore. The person that wrote these has been gone probably 5 years, if not longer. I'm sorry I am not giving whatever info is being looked for. I'm not even sure what is desired. If you all think it is frustrating for you, imagine what it is like for me, when I don't even know perl terminology. I am giving you the info I know.

The script itself is run from cli. It doesn't go through any sort of gui or webpage, just cli.

The include/exclude is unimportant. The only thing that goes in those files are names to be either included or excluded from the output.
As stated, the script already gives up to today's date. I just want to modify the script to do from X date, to today's date.

If that is the $dateout variable, then I'll figure that out. If this info just isn't helpful for anything, I'll just figure out a different way to do what I need.

I'm not trying to be difficult, I am just poor with understanding other peoples terminology. However, need help rebuilding a brushless motor? How about a 3-phase alternator or maybe using a flowbench to port a head?

scasey 04-25-2019 04:35 PM

Quote:

Originally Posted by vinmansbrew (Post 5988518)
The start date was arbitrary, I just picked that date.
Would I put the $dateout variable before or after the current $dateout variable?

I was given this mainly cause I drew the short straw. No one here does perl anymore. The person that wrote these has been gone probably 5 years, if not longer. I'm sorry I am not giving whatever info is being looked for. I'm not even sure what is desired. If you all think it is frustrating for you, imagine what it is like for me, when I don't even know perl terminology. I am giving you the info I know.

The script itself is run from cli. It doesn't go through any sort of gui or webpage, just cli.

The include/exclude is unimportant. The only thing that goes in those files are names to be either included or excluded from the output.
As stated, the script already gives up to today's date. I just want to modify the script to do from X date, to today's date.

If that is the $dateout variable, then I'll figure that out. If this info just isn't helpful for anything, I'll just figure out a different way to do what I need.

I'm not trying to be difficult, I am just poor with understanding other peoples terminology. However, need help rebuilding a brushless motor? How about a 3-phase alternator or maybe using a flowbench to port a head?

I feel your pain.

Your new variable would have a different name...something like $datestart...I don't know the exact syntax for setting an arbitrary date using Time::Piece I'd have to read the documentation.

Again, frankly, we don't see anywhere that the current date ($dateout) is used at all, except to define the directory in which the file newstudents.list is contained, so I can't see where knowing some arbitrary start date is going to help you do anything.

What is your vision/expectation to be able to do with the date once you've got it?
What are you trying to accomplish here?
Only getting new(ish) records from the ldap? That would require modifying the query to the ldap. Do you know how to do that?

individual 04-25-2019 09:43 PM

This should give you something to play around with.
Code:

use strict;
use warnings;
use Time::Piece;

my $d = shift or die "give a date in YearMonthDay form";
my $start_date = Time::Piece->strptime($d, "%Y%m%d");
my $end_date = Time::Piece->new;

while ($start_date <= $end_date) {
    my $infile = "output/" . $start_date->strftime("%Y%m%d") . "/newstudents.list";
   
    # do something with infile

    $start_date += 86400; # Increment by 24 hours.
}

Also, file handles should be lexical, i.e. my $filehandle. :)


All times are GMT -5. The time now is 05:57 PM.