I have an issue and this is rather my last resort before I give up, Im rather a noob with Perl and I've about reached the end of the internet searching for a solution.
***I do not have permission to install anything so it must be native to Perl5
I have a script and I need to calculate the total runtime of the script, and output the result in 00.00 "minutes.seconds" stored in a variable.
Here's a failed attempt:
#!/usr/bin/perl
use Time::Piece;
use POSIX qw(strftime);
my $start = localtime->strftime($unixtime);
sleep(10);
my $end = localtime->strftime($unixtime);
my $diff = $end - $start;
my $runtime = printf("%M.%S", $diff);
print $runtime;
I definitely have played with this a bit and was able to get "10" seconds as a result, however that is not the proper format. If the script ran for say 10 seconds, the output should be "00.10".
If the script ran for say 1 minute and 55 seconds the output should be "01.55".
Is there any way this can be done?
I searched on this and found 1 article however not even close... REF: perl different time format output
No need for Time::Piece!
my $start = time;
sleep(10);
my $end = time;
my $diff = $end - $start;
my $runtime = sprintf '%d:%02d', int($diff / 60), $diff % 60;
print "$runtime\n";
This should do the trick:
#!/usr/bin/perl
use Time::Piece;
my $start = localtime;
sleep(10);
my $end = localtime;
my $diff = $end - $start;
my $minutes = int $diff->minutes;
my $seconds = $diff->seconds % 60;
my $output = sprintf '%02d.%02d', $minutes, $seconds;
print "$output\n";
Related
I'm creating a script where I need to get the Last Modified Date of the files
I checked this thread How do I get a file's last modified time in Perl?
So I used the script below to get the last modified, at first it was working but when I try to run it again, the timestamp returns 00:00 January 1, 1970.
Why is that happening and how can I get the correct last modified date and time?
my $dir = '/tmp';
opendir(DIR, $dir) or die $!;
#content=readdir(DIR);
foreach(#content)
{
next unless ($_ =~ m/\bfile.txt|file2.csv\b/);
my $epoch_timestamp = (stat($_))[9];
my $timestamp = localtime($epoch_timestamp);
$f_detail = $_ .' '.$timestamp;
print "$f_detail\n";
}
closedir(DIR);
exit 0;
When I tried to run the perl, I will get this result
file.txt Thu Jan 1 00:00:00 1970
file2.csv Thu Jan 1 00:00:00 1970
Ok, last update, it is working now, I try to run all of the scripts you've given to me, standalone script. I found what's causing the default time, see the script below, I remove that in my program and it works, didn't notice this at first, sorry. But still, it feels weird because I was sure that it is working when I first run it, but now it is working so yeah thank you guys!
if (($month = ((localtime)[4] + 1)) < 10)
{
$month = '0' . $month;
}
if (($day = ((localtime)[3])) < 10)
{
$day = '0' . $day;
}
if (($year = ((localtime)[5]+1900)) >= 2000)
{
if (($year = $year - 2000) < 10)
{
$year = '0' . $year;
}
}
else
{
$year = $year - 1900;
}
$date = $month . $day . $year;
readdir returns file names without the full path. You need to prepend the path manually:
for (#content) {
next unless /^(?:file\.txt|file2\.csv)\z/;
my $epoch_timestamp = (stat("$dir/$_"))[9];
# ~~~~~~~~~
Also note how I changed the regex to match the file names.
If you have a directory name, and you want to see if some files whose names you already know exist in that directory, there's really no need for opendir/readdir - that's more helpful if you don't know the filenames ahead of time. When you do, you can just build a path using both parts and use file test operators/stat/etc. on it.
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
my $dir = '/tmp';
my #files = qw/file.txt file2.csv/;
for my $file (#files) {
# Better to use File::Spec->catfile($dir, $file), but your question
# title said no modules...
my $name = "$dir/$file";
if (-e $name) { # Does the file exist?
# _ to re-use the results of the above file test operator's stat call
my $epoch_timestamp = (stat _)[9];
my $timestamp = localtime $epoch_timestamp;
say "$file $timestamp";
}
}
Example execution:
$ perl demo.pl
file.txt Tue Feb 8 07:26:07 2022
file2.csv Tue Feb 8 07:26:10 2022
Following demo code utilizes glob to obtain modification time for specified files in a directory.
use strict;
use warnings;
use feature 'say';
my $dir = '/tmp';
my #files = qw(file.txt file2.csv);
my $mask = join ' ', map { "$dir/$_" } #files;
say "$_\t" . localtime((stat($_))[9]) for glob($mask);
My code is:
#!/usr/local/bin/perl
use Time::Piece;
use Time::HiRes;
use strict;
use warnings 'all';
my $i = 1;
my $starttime = localtime->strftime('%Y%m%d%H%M');
open my $file, '>', 'order.properties' or die $!;
for ($i = 1; $i <= 10; $i++){
print $file "Start_time_$i = $starttime\n";
sleep (120);
}
close $file;
In the above code I am creating an order.properties file and writing a variable called Starttime and assigning date and time in a format of YYYYMMDDHH24MM and iterating the variable for 10 time with sleep time 2 mins, but sleep is not working and after adding sleep function to the Script, it's just creating a file not writing anything into it.
For each iteration of for loop I need 2 mins of sleep like:
Start_time_1 = 201812141350
Start_time_2 = 201812141352
The output should be like above.
You set $starttime outside of the loop and never change it. Therefore it always has the same value. If you want it to change in the loop, then you need to change it in the loop.
for ($i = 1; $i <= 10; $i++){
my $starttime = localtime->strftime('%Y%m%d%H%M');
print $file "Start_time_$i = $starttime\n";
sleep (120);
}
Of course, at that point, you have to wonder if there's any good reason to have the variable at all.
for ($i = 1; $i <= 10; $i++){
print $file "Start_time_$i = ", localtime->strftime('%Y%m%d%H%M'), "\n";
sleep (120);
}
And, please make your maintenance programmer's life easier by using a foreach loop there.
foreach my $i (1 .. 10) {
print $file "Start_time_$i = ", localtime->strftime('%Y%m%d%H%M'), "\n";
sleep (120);
}
I am trying to create a perl script that tests a bunch of mirror servers for the best mirror to use.
What is the best method to see how long it takes to download a file? I am trying to avoid system calls like
$starttime = time();
$res = `wget -o/dev/null SITE.com/file.txt`;
$endtime = time();
$elapsed = $endtime - $starttime;
I'd rather use Perl functions
You can use LWP::Simple or HTTP::Tiny (which is built in since 5.14.0).
use strict;
use warnings;
use v5.10; # for say()
use HTTP::Tiny;
use Time::HiRes qw(time); # to measure less than a second
use URI;
my $url = URI->new(shift);
# Add the HTTP scheme if the URL is schemeless.
$url = URI->new("http://$url") unless $url->scheme;
my $start = time;
my $response = HTTP::Tiny->new->get($url);
my $total = time - $start;
if( $response->{success} ) {
say "It took $total seconds to fetch $url";
say "The content was #{[ length $response->{content} ]} bytes";
}
else {
say "Fetching $url failed: $response->{status} $response->{reason}";
}
I am working on a perl script to add days to a date and display the newdate:
use Time::ParseDate;
use Time::CTime;
my $date = "02/01/2003";
my $numdays = 30;
my $time = parsedate($date);
# add $numdays worth of seconds
my $newtime = $time + ($numdays * 24 * 60 * 60);
my $newdate = strftime("%m/%d/%Y",localtime($newtime));
print "$newdate\n";
The output will be:
03/03/2003
Now how do I set the input for the date field to be yyyymmdd Ex: my $date = "20030102"
Also the output will need to be : 20030303
Thanks
You use Time::Piece + Time::Seconds (in core since Perl 5.10),
use Time::Piece ();
use Time::Seconds;
my $date = '20030102';
my $numdays = 60; # 30 doesn't get us to march
my $dt = Time::Piece->strptime( $date, '%Y%m%d');
$dt += ONE_DAY * $numdays;
print $dt->strftime('%Y%m%d');
You can use DateTime + DateTime::Format::Strptime:
#!/usr/bin/perl
use strict;
use DateTime;
use DateTime::Format::Strptime;
my $strp = DateTime::Format::Strptime->new(
pattern => '%m/%d/%Y'
);
# convert date to
my $date = '02/01/2003';
my $dt = $strp->parse_datetime($date);
printf "%s -> %s\n", $date, $dt->add(days => 30)->strftime("%d/%m/%Y");
OUTPUT
02/01/2003 -> 03/03/2003
Convert $date from the input format to the old format:
$date =~ s%(....)(..)(..)%$3/$2/$1%;
If the output format should not be %m/%d/%Y, then do not set it to it. You obviously need %Y%m%d.
I am attempting to write a Perl script that parses a log where on each line the second value is the date. The script takes in three arguments: the input log file, the start time, and the end time. The start and end time are used to parse out a certain value on each line that that falls between those two times. But to properly run this I am converting the start and end time to epoch time. The problem I am having is that to convert the loops 'i' value back to normal time to compare against the log file. After running localtime($i) I print the value and only see a reference printed not the actual value.
Here is the script I have so far (it is a work in progress):
#!/usr/bin/perl
use strict;
use warnings;
use Time::Local;
use Time::localtime;
use File::stat;
my $sec = 0;
my $min = 0;
my $hour = 0;
my $mday = 0;
my $mon = 0;
my $year = 0;
my $wday = 0;
my $yday = 0;
my $isdst = 0;
##########################
# Get the engine log date
##########################
my $date = `grep -m 1 'Metric' "$ARGV[0]" | awk '{print \$2}'`;
($year,$mon,$mday) = split('-', $date);
$mon--;
#########################################
# Calculate the start and end epoch time
#########################################
($hour,$min,$sec) = split(':', $ARGV[1]);
my $startTime = timelocal($sec,$min,$hour,$mday,$mon,$year);
($hour,$min,$sec) = split(':', $ARGV[2]);
my $endTime = timelocal($sec,$min,$hour,$mday,$mon,$year);
my $theTime = 0;
for (my $i = $startTime; $i <= $endTime + 29; $i++) {
#print "$startTime $i \n";
$theTime = localtime($i);
#my $DBInstance0 = `grep "$hour:$min:$sec" "$ARGV[0]"`;# | grep 'DBInstance-0' | awk '{print \$9}'`;
#print "$DBInstance0\n";
print "$theTime\n";
}
print "$startTime $endTime \n";
The output looks like:
Time::tm=ARRAY(0x8cbbd40)
Time::tm=ARRAY(0x8cbc1a0)
Time::tm=ARRAY(0x8cbbe80)
Time::tm=ARRAY(0x8cbc190)
Time::tm=ARRAY(0x8bbb170)
Time::tm=ARRAY(0x8cbc180)
Time::tm=ARRAY(0x8cbbf30)
Time::tm=ARRAY(0x8cbc170)
Time::tm=ARRAY(0x8cbc210)
Time::tm=ARRAY(0x8cbc160)
1275760356 1275760773
I only have access to the core Perl modules and am unable to install any others.
You can use ctime, depending on your definition of "Normal time":
Example code:
use Time::Local;
use Time::localtime;
my $time=timelocal(1,2,3,24,6,2010);
print "$time\n";
$theTime = ctime($time);
print "$theTime\n";
Result:
1279954921
Sat Jul 24 03:02:01 2010
Also, you don't need to use Time::Localtime (which is why you get Time::tm instead of a standard array/string from Perl's internal localtime):
use Time::Local;
my $time=timelocal(1,2,3,24,6,2010);
print "$time\n";
$theTime = localtime($time);
print "$theTime\n";
1279954921
Sat Jul 24 03:02:01 2010
Don't forget to subtract 1900 from the year!
Remember that in scalar context, localtime and gmtime returns a ctime-formatted string, so you could use it as in the following. If that's unsuitable, you might want to use strftime from the POSIX module.
#! /usr/bin/perl
use warnings;
use strict;
use Time::Local;
my $start = "01:02:03";
my $end = "01:02:05";
my $date = "2010-02-10";
my($year,$mon,$mday) = split /-/, $date;
$mon--;
$year -= 1900;
my($startTime,$endTime) =
map { my($hour,$min,$sec) = split /:/;
timelocal $sec,$min,$hour,$mday,$mon,$year }
$start, $end;
for (my $i = $startTime; $i <= $endTime + 29; $i++) {
print scalar localtime($i), "\n";
}
print "$startTime $endTime \n";
Tail of the output:
Wed Feb 10 01:02:26 2010
Wed Feb 10 01:02:27 2010
Wed Feb 10 01:02:28 2010
Wed Feb 10 01:02:29 2010
Wed Feb 10 01:02:30 2010
Wed Feb 10 01:02:31 2010
Wed Feb 10 01:02:32 2010
Wed Feb 10 01:02:33 2010
Wed Feb 10 01:02:34 2010
1265785323 1265785325