how to use logrotate for keeping compressed 5 days files by excluding current date log files - logrotate

Log files mentioned as below in /var/log/
340 Mar 1 10:36 sql-20220301.log
350913 Mar 1 10:43 sql-20220301.csv
1298450 Mar 2 17:59 sql-20220302.log
1689208 Mar 2 17:59 sql-20220302.csv
3207594 Mar 3 17:59 sql-20220303.log
2250155 Mar 3 17:59 sql-20220303.csv
3200691 Mar 4 17:59 sql-20220304.log
2144001 Mar 4 17:59 sql-20220304.csv
3200691 Mar 5 17:59 sql-20220305.log
2139968 Mar 5 17:5 sql-20220305.csv
3200691 Mar 6 17:59 sql-20220306.log
2140712 Mar 6 17:59 sql-20220306.csv
3202992 Mar 7 17:59 sql-20220307.log
2158303 Mar 7 17:59 sql-20220307.csv
3212196 Mar 8 17:59 sql-20220308.log
2175547 Mar 8 17:59 sql-20220308.csv
2237950 Mar 9 12:31 sql-20220309.log
1661695 Mar 9 17:30 sql-20220309.csv
Assume that current date is mar 9 , i want to keep this as original by keeping 5 days (mar 4- mar8) both .log and .csv as .gz files.
created conf file in /etc/logroatate.d/sqlchck as
/var/log/.log /var/log/.csv {
daily
rotate 5
compress
delaycompress
dateext
nocopytruncate
notifempty
missingok
}
it doesn't works as expected.
i need below result as
3200691 Mar 4 17:59 sql-20220304.log.gz
2144001 Mar 4 17:59 sql-20220304.csv.gz
3200691 Mar 5 17:59 sql-20220305.log.gz
2139968 Mar 5 17:5 sql-20220305.csv.gz
3200691 Mar 6 17:59 sql-20220306.log.gz
2140712 Mar 6 17:59 sql-20220306.csv.gz
3202992 Mar 7 17:59 sql-20220307.log.gz
2158303 Mar 7 17:59 sql-20220307.csv.gz
3212196 Mar 8 17:59 sql-20220308.log.gz
2175547 Mar 8 17:59 sql-20220308.csv.gz
2237950 Mar 9 12:31 sql-20220309.log
1661695 Mar 9 17:30 sql-20220309.csv

Related

My symbol column file size in partitioned table is unusually large -- why would that be?

I've just built my first proper q/kdb+ database with splayed and partitioned tables. Everything is going fine, but I just noticed that my symbol s column file size is unusually large. Here is what I can see from the OS and from inside q:
# ls -latr 2017.10.30/ngbarx
total 532
-rw-r--r-- 1 root root 24992 Apr 17 20:53 vunadj
-rw-r--r-- 1 root root 24992 Apr 17 20:53 v
-rw-r--r-- 1 root root 300664 Apr 17 20:53 s
...
q)meta ngbarx
c | t f a
------| -----
date | d
s | s p
v | e
vunadj| e
...
q)get `:2017.10.30/ngbarx/s
`p#`sym$`A`AA`AACG`AADI`AADR`AAIC`AAIC-B`AAL`AAM-A`AAMC`AAME`AAOI`AAON`AAP`AA..
q)-22!get `:2017.10.30/ngbarx/v
24990
q)-22!get `:2017.10.30/ngbarx/s
28678
q)all (get `:2017.10.30/ngbarx/s) in sym
1b
q)count sym
62136
So comparing the real-type v column with the symbol-type s column, I see from ls that the symbol column is more than 10x the size, even though the internal size in bytes is similar and everything seems properly encoded in the sym file.
Is this expected behavior? Or am I doing something wrong that could be fixed?
UPDATE: I have not used compression, and have written the files using the magical function .Q.dcfgnt, which can be viewed here. Well, a slightly modified version, I noticed that this function as is also saved a date file in the directory, even though the column should be virtual, so I did some hacking in k (I'm not very good at it) and updated the inner function .Q.dpfgnt to this ...
k){[d;p;f;g;n;t]if[~&/qm'r:+en[d]t;'`unmappable];
{[d;g;t;i;x]#[d;x;g;t[x]i]}[d:par[d;p;n];g;r;<r f]'{x#&~x=`date}(!r);
#[;f;`p#]#[d;`.d;:;f,r#&~f=r:{x#&~x=`date}(!r)];n}
Applying the parted attribute is not free and requires storage. It is usually not that costly but looking at your sample output of s, it doesn't look suitable for parting as does not contain repeating values:
q)get `:2017.10.30/ngbarx/s
`p#`sym$`A`AA`AACG`AADI`AADR`AAIC`AAIC-B`AAL`AAM-A`AAMC`AAME`AAOI`AAON`AAP`AA..
See below tables created to illustrate the issue:
/ no part - 16 distinct syms
t1:([]s:100000?`1;v:100000?2e)
/ part - 16 distinct syms
t2:update `p#s from `s xasc ([]s:100000?`1;v:100000?2e)
/ no part - 99999 distinct syms
t3:([]s:100000?`8;v:100000?2e)
/ part - 99999 distinct syms
t4:update `p#s from `s xasc ([]s:100000?`8;v:100000?2e)
The difference in size is insignificant between t1 and t2 with the parted attribute(804096 -> 804664). However, when the number of distinct syms / parts becomes very large, the storage cost is very large. (804096 -> 4749872)
ls | xargs ls -latr
t1:
total 1180
-rw-r--r-- 1 matmoore matmoore 12 Apr 19 10:28 .d
-rw-r--r-- 1 matmoore matmoore 804096 Apr 19 10:28 s
-rw-r--r-- 1 matmoore matmoore 400016 Apr 19 10:28 v
drwxr-xr-x 1 matmoore matmoore 4096 Apr 19 10:28 .
drwxr-xr-x 1 matmoore matmoore 4096 Apr 19 10:28 ..
t2:
total 1180
-rw-r--r-- 1 matmoore matmoore 12 Apr 19 10:28 .d
-rw-r--r-- 1 matmoore matmoore 804664 Apr 19 10:28 s
-rw-r--r-- 1 matmoore matmoore 400016 Apr 19 10:28 v
drwxr-xr-x 1 matmoore matmoore 4096 Apr 19 10:28 .
drwxr-xr-x 1 matmoore matmoore 4096 Apr 19 10:28 ..
t3:
total 1180
-rw-r--r-- 1 matmoore matmoore 12 Apr 19 10:28 .d
-rw-r--r-- 1 matmoore matmoore 804096 Apr 19 10:28 s
-rw-r--r-- 1 matmoore matmoore 400016 Apr 19 10:28 v
drwxr-xr-x 1 matmoore matmoore 4096 Apr 19 10:28 .
drwxr-xr-x 1 matmoore matmoore 4096 Apr 19 10:28 ..
t4:
total 5032
-rw-r--r-- 1 matmoore matmoore 12 Apr 19 10:28 .d
drwxr-xr-x 1 matmoore matmoore 4096 Apr 19 10:28 ..
-rw-r--r-- 1 matmoore matmoore 4749872 Apr 19 10:28 s
-rw-r--r-- 1 matmoore matmoore 400016 Apr 19 10:28 v
drwxr-xr-x 1 matmoore matmoore 4096 Apr 19 10:28 .
I would also question if this column should be a symbol. If 62k is the size of your sym file with just one date created then you should be careful that you are going to end up creating a bloated sym file. If you have a full history from 2017.10.30 and the sym file is still 62k, then it's fine but if you are adding that many new symbols each day, the sym file will quickly spiral out of control.

First program in bash pipeline is blocking

I'm trying to pipe several perl programs together, and from everything I've read, piped programs are supposed to all open and run in parallel. That doesn't appear to be the case with whatever it is that I did. Here is the simplified version:
./video
#!/usr/bin/env perl
my $i = 0;
while($i<10){
my $time = localtime(time);
print "VID: $time $i\n";
sleep 1;
$i++;
}
./controller
#!/usr/bin/env perl
while(my $line = <STDIN>){
my $time = localtime(time);
print "CTRL: $time $line";
}
./pipes
#!/usr/bin/env perl
open(my $controller, "|./controller") || die "Can't fork: $!";
open(STDOUT, ">&", $controller);
open(my $video, "|./video") || die "Can't fork: $!";
print STDERR "All processes started\n";
I tried executing it two ways, but both resulted in the same output:
<16:34:21> rswhiting#Minas-Tirith:~/code/Pipes $ ./pipes
All processes started
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:22 2014 0
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:23 2014 1
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:24 2014 2
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:25 2014 3
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:26 2014 4
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:27 2014 5
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:28 2014 6
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:29 2014 7
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:30 2014 8
CTRL: Sun Apr 20 16:34:32 2014 VID: Sun Apr 20 16:34:31 2014 9
<16:34:49> rob#Minas-Tirith:~/code/Pipes $ ./video | ./controller
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:15 2014 0
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:16 2014 1
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:17 2014 2
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:18 2014 3
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:19 2014 4
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:20 2014 5
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:21 2014 6
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:22 2014 7
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:23 2014 8
CTRL: Sun Apr 20 16:35:25 2014 VID: Sun Apr 20 16:35:24 2014 9
<16:35:25> rob#Minas-Tirith:~/code/Pipes $
The timestamps from the video program increment as they should, but the time that the control program receives them is identical (after the video program has ended). How do I make the controller receive the data as it is produced instead of after the fact?
It's because of STDOUT buffering in the video program. print is line-buffered only if it goes to an interactive terminal. Otherwise it uses a much bigger buffer, and the accumulated output is emitted in one big chunk when video exits. Try flushing after each print or use autoflush.
$| = 1; # Enables autoflush
By the way I don't get why you open a pipe TO video, it does not read anything. It should be
system "./video";
If you have a program that you can't modify but does not autoflush, you are in trouble. Except, you're not. You can use a pseudoterminal instead of a pipe. I've never done it. But chapter 64 of the book "The UXIX Programming Interface" is about pseudoterminals.

How to get first day of last month with Perl

So I would like to use function localtime(), but I'm having problems with getting first and last day of last month properly. Right now I have working functionality, but I bet there is a better way to solve this.
use Time::Piece;
use Time::Seconds;
$start_of_month = localtime();
while($start_of_month->mday < 10) {
$start_of_month += ONE_DAY;
}
$start_of_month -= ONE_MONTH; # Subtract one month to get previous month. "ONE_MONTH" is defined by Time::Seconds
$end_of_month = $start_of_month; # Copy start_of_month to end_of_month as they both have same year and month.
# Subtract day from $start_of_month until mday is the first day of the month.
while($start_of_month->mday != 1) {
$start_of_month -= ONE_DAY;
}
# Silly workaround to bring $end_of_month to last day of the month as Time::Piece object does not have good way to change mday.
while($end_of_month->mday != $start_of_month->month_last_day) {
$end_of_month += ONE_DAY;
}
$period_start = $start_of_month->dmy("."); # End result has to be same!
Can anyone give me a better way of handling this?
Don't rely on Time::Piece and constants in Time::Seconds for date manipulation
The following was my suggested simplification of the OP's date manipulation using Time::Piece and Time::Seconds. IF this worked on overloaded operators, it might actually work as intended, but as ikegami pointed out, this isn't guaranteed. So I tested below.
If you want to go the math route, at least you could simplify things a little:
use strict;
use warnings;
use Time::Piece;
use Time::Seconds;
my $date_start = localtime();
$date_start -= ONE_MONTH;
$date_start -= ($date_start->mday - 1) * ONE_DAY;
my $date_end = $date_start + ($date_start->month_last_day - 1) * ONE_DAY;
print $date_start , "\n"; # Prints Mar 1st (at least today it does)
print $date_end , "\n"; # Prints Mar 31st
I'd consider using a different module for this, like Date::Calc or DateTime, but this might work for your purposes.
Testing the above solution - many failures
I created a script the below script that loops through every date for a year starting at January 15th, showing every range where the above code does not work as expected.
use strict;
use warnings;
use Time::Piece;
use Time::Seconds;
my $t = 1389812400; # Wed 2014-Jan-15 7pm GMT. 11am PST
my $t_max = 1421348400; # Thu 2015-Jan-15 7pm GMT. 11am PST
my %prev_month = map {$_ => ($_ - 1) || 12} (1..12);
my $fail = '';
while ($t <= $t_max) {
$t += 60; # Increment by 1 minute
# Testing potentially overloaded math of Time::Piece & Time::Seconds
my $start = my $src = localtime($t);
$start -= ONE_MONTH;
$start -= ($start->mday - 1) * ONE_DAY;
if ($start->mon != $prev_month{$src->mon}) {
print "From ($t) $src -> $start\n" if !$fail;
$fail = " To ($t) $src -> $start\n\n";
} elsif ($fail) {
print $fail;
$fail = '';
}
}
The below is the output of this script with comments inserted to explain why each range fails:
# ONE_MONTH is exactly 2_629_744 seconds, or 30.437 days.
# ONE_MONTH is too short for January
From (1391193000) Fri Jan 31 10:30:00 2014 -> Wed Jan 1 00:00:56 2014
To (1391241540) Fri Jan 31 23:59:00 2014 -> Wed Jan 1 13:29:56 2014
# ONE_MONTH is too long for February
From (1393660800) Sat Mar 1 00:00:00 2014 -> Wed Jan 1 13:30:56 2014
To (1393871340) Mon Mar 3 10:29:00 2014 -> Wed Jan 1 23:59:56 2014
# ONE_MONTH is too short for March
From (1396290600) Mon Mar 31 11:30:00 2014 -> Sat Mar 1 00:00:56 2014
To (1396335540) Mon Mar 31 23:59:00 2014 -> Sat Mar 1 12:29:56 2014
# ONE_DAY is 86_400 seconds, or 24 hours.
# March 9th is only 23 hours long due to DST, ONE_DAY goes to far.
From (1397064600) Wed Apr 9 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397068140) Wed Apr 9 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397151000) Thu Apr 10 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397154540) Thu Apr 10 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397237400) Fri Apr 11 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397240940) Fri Apr 11 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397323800) Sat Apr 12 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397327340) Sat Apr 12 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397410200) Sun Apr 13 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397413740) Sun Apr 13 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397496600) Mon Apr 14 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397500140) Mon Apr 14 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397583000) Tue Apr 15 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397586540) Tue Apr 15 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397669400) Wed Apr 16 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397672940) Wed Apr 16 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397755800) Thu Apr 17 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397759340) Thu Apr 17 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397842200) Fri Apr 18 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397845740) Fri Apr 18 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1397928600) Sat Apr 19 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1397932140) Sat Apr 19 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398015000) Sun Apr 20 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398018540) Sun Apr 20 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398101400) Mon Apr 21 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398104940) Mon Apr 21 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398187800) Tue Apr 22 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398191340) Tue Apr 22 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398274200) Wed Apr 23 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398277740) Wed Apr 23 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398360600) Thu Apr 24 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398364140) Thu Apr 24 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398447000) Fri Apr 25 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398450540) Fri Apr 25 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398533400) Sat Apr 26 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398536940) Sat Apr 26 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398619800) Sun Apr 27 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398623340) Sun Apr 27 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398706200) Mon Apr 28 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398709740) Mon Apr 28 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398792600) Tue Apr 29 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398796140) Tue Apr 29 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
From (1398879000) Wed Apr 30 10:30:00 2014 -> Fri Feb 28 23:00:56 2014
To (1398882540) Wed Apr 30 11:29:00 2014 -> Fri Feb 28 23:59:56 2014
# ONE_MONTH is too long for April
From (1398927600) Thu May 1 00:00:00 2014 -> Sat Mar 1 12:30:56 2014
To (1398965340) Thu May 1 10:29:00 2014 -> Sat Mar 1 22:59:56 2014
# ONE_MONTH is too short for May
From (1401557400) Sat May 31 10:30:00 2014 -> Thu May 1 00:00:56 2014
To (1401605940) Sat May 31 23:59:00 2014 -> Thu May 1 13:29:56 2014
# ONE_MONTH is too long for June
From (1404198000) Tue Jul 1 00:00:00 2014 -> Thu May 1 13:30:56 2014
To (1404235740) Tue Jul 1 10:29:00 2014 -> Thu May 1 23:59:56 2014
# ONE_MONTH is too short for July
From (1406827800) Thu Jul 31 10:30:00 2014 -> Tue Jul 1 00:00:56 2014
To (1406876340) Thu Jul 31 23:59:00 2014 -> Tue Jul 1 13:29:56 2014
# ONE_MONTH is too short for August
From (1409506200) Sun Aug 31 10:30:00 2014 -> Fri Aug 1 00:00:56 2014
To (1409554740) Sun Aug 31 23:59:00 2014 -> Fri Aug 1 13:29:56 2014
# ONE_MONTH is too long for September
From (1412146800) Wed Oct 1 00:00:00 2014 -> Fri Aug 1 13:30:56 2014
To (1412184540) Wed Oct 1 10:29:00 2014 -> Fri Aug 1 23:59:56 2014
# ONE_MONTH is too short for October
From (1414776600) Fri Oct 31 10:30:00 2014 -> Wed Oct 1 00:00:56 2014
To (1414825140) Fri Oct 31 23:59:00 2014 -> Wed Oct 1 13:29:56 2014
# ONE_MONTH is too long for November
From (1417420800) Mon Dec 1 00:00:00 2014 -> Wed Oct 1 14:30:56 2014
To (1417454940) Mon Dec 1 09:29:00 2014 -> Wed Oct 1 23:59:56 2014
# ONE_MONTH is too short for December
From (1420050600) Wed Dec 31 10:30:00 2014 -> Mon Dec 1 00:00:56 2014
To (1420099140) Wed Dec 31 23:59:00 2014 -> Mon Dec 1 13:29:56 2014
Alternative using Time::Piece->add_months? Nope
Time::Piece has two functions, add_months and add_years intended for date calculations. Unfortunately, the documentation states:
Note that there is some "strange" behaviour when adding and subtracting months at the ends of months. Generally when the resulting month is shorter than the starting month then the number of overlap days is added. For example subtracting a month from 2008-03-31 will not result in 2008-02-31 as this is an impossible date. Instead you will get 2008-03-02. This appears to be consistent with other date manipulation tools.
The below code fully demonstrates this behavior for the timezone PST.
use strict;
use warnings;
use Time::Piece;
my $t = localtime(1420012800);
print $t->add_months($_),"\n" for (0..12)
Output:
Wed Dec 31 00:00:00 2014
Sat Jan 31 00:00:00 2015
Tue Mar 3 00:00:00 2015
Tue Mar 31 00:00:00 2015
Fri May 1 00:00:00 2015
Sun May 31 00:00:00 2015
Wed Jul 1 00:00:00 2015
Fri Jul 31 00:00:00 2015
Mon Aug 31 00:00:00 2015
Thu Oct 1 00:00:00 2015
Sat Oct 31 00:00:00 2015
Tue Dec 1 00:00:00 2015
Thu Dec 31 00:00:00 2015
Now, it is kind of nice how this function is able to accurately cycle back to the same date a year later, but there are lots of unfavorable months until then.
Conclusion
The constants in Time::Seconds are just that, constants. They are exact numbers of seconds meant to represent periods of time. There is no operator overloading to facilitate fancy date manipulation. Instead, these values are simply good for mathematical comparisons.
To manipulate specific dates, I'd advise using Date::Calc, DateTime, or any of the other modules suggested in this question.
A less OO, but alternate solution:
use POSIX qw(mktime);
my #now = localtime;
# mday = 1, month = month - 1
my $date_start = mktime(#now[0 .. 2], 1, $now[4] - 1, #now[5 .. 8]);
# mday = 0, the 0th day of this month == last day of prior month
my $date_end = mktime(#now[0 .. 2], 0, #now[4 .. 8]);
print scalar localtime $date_start, "\n";
print scalar localtime $date_end, "\n";
This hiccups with daylight saving time; if you don't care about time-of-day you could set $now[2] to 12 noon and hope no country declares night to be day and day to be night:
my #now = (0, 0, 12, (localtime)[3..8]);
I don't trust code that uses Time::Piece. It relies on overloading operators to make it look like you're doing it wrong ($time += ONE_DAY; looks like you're adding a constant) when you're actually doing it right. Maybe. It's hard to tell. You must have intimate knowledge of the guts of the module to know if you're doing it right.
DateTime solution:
my $dt = DateTime
->now( time_zone => 'local' )
->set_time_zone('floating') # Do this when you want to date arithmetic.
->truncate( to => 'day' );
$dt->set( day => 1 )->subtract( days => 1 );
my $last = $dt->ymd('-');
$dt->set( day => 1 );
my $first = $dt->ymd('-');
say "$first .. $last";
Using the Time::Seconds definition of ONE_MONTH gives you a solution that is wrong for several days a year. It is the average length of a month in seconds, and is equal to about 30.4 days. Subtracting that from 1 March, for instance, gives you a date in late January.
However the first day of the previous month can be calculated simply from the month and day fields returned by localtime. Converting this into a Time::Piece object lets us calculate the last day of the same month.
use strict;
use warnings;
use Time::Piece;
my ($m, $y) = (localtime)[4,5];
$y += 1900;
if ($m == 0) {
$m = 11;
$y -= 1;
}
my $period_start = sprintf '%02d.%02d.%04d', 1, $m, $y;
my $period_end = do {
my $tp = Time::Piece->strptime($period_start, '%d.%m.%Y');
sprintf '%02d.%02d.%04d', $tp->month_last_day, $m, $y;
};
print $period_start, "\n";
print $period_end, "\n";
output
01.03.2014
31.03.2014
Sorry if I did not understood property but: DaysInMonth (check coment)
my #monthDays= qw( 31 28 31 30 31 30 31 31 30 31 30 31 );
sub MonthDays {
my $month= shift(#_);
my $year= #_ ? shift(#_) : 1900+(localtime())[5];
if( $year <= 1752 ) {
# Note: Although September 1752 only had 19 days,
# they were numbered 1,2,14..30!
return 19 if 1752 == $year && 9 == $month;
return 29 if 2 == $month && 0 == $year % 4;
} else {
return 29 if 2 == $month and
0 == $year%4 && 0 != $year%100 || 0 == $year%400;
}
return $monthDays[$month-1];
}
If you wish easy data to seconds then take look Time::Local
$time = timelocal( $sec, $min, $hour, $mday, $mon, $year );

Hash to convert month to number

I am using hash to convert month into number.
%mon2num = qw(
jan 1 feb 2 mar 3 apr 4 may 5 jun 6
jul 7 aug 8 sep 9 oct 10 nov 11 dec 12
);
Here i want to make all month jan, feb..dec case insensitive.Let me know how to do.
Use lc:
for my $month (qw(Jan FEB mar)) {
print "$month --> ", $mon2num{lc $month}, "\n";
}

copy specific file in command line

I want to copy specific file done last changes in Oct 16-17,file type is java.
shia#ubuntu:~/code$ ls -alxo
total 96
drwx------ 2 shia 4096 Oct 20 18:54 .
drwxr-xr-x 61 shia 12288 Oct 20 19:24 ..
-rw------- 1 shia 12288 Oct 16 21:52 .Reuse.java.swp
-rw-rw-r-- 1 shia 746 Oct 20 11:16 Argus.class
-rw-rw-r-- 1 shia 302 Oct 20 11:16 Argus.java
-rw------- 1 shia 310 Oct 16 21:30 Call.java
-rw-rw-r-- 1 shia 417 Oct 17 15:20 Ordinary.class
-rw-rw-r-- 1 shia 298 Oct 17 14:57 Overriding.java
-rw-rw-r-- 1 shia 562 Oct 19 21:27 Package.class
-rw-rw-r-- 1 shia 430 Oct 19 21:27 Package.java
-rw------- 1 shia 729 Oct 17 13:50 Reuse.java
-rw------- 1 shia 424 Oct 17 13:47 Room.java
-rw------- 1 shia 321 Oct 16 21:22 Simpleobject.java
-rw-rw-r-- 1 shia 1187 Oct 17 00:04 Static.java
-rw-rw-r-- 1 shia 686 Oct 17 15:20 Super.class
-rw-rw-r-- 1 shia 1010 Oct 17 15:20 Super.java
-rw------- 1 shia 843 Oct 17 14:20 This.java
-rw-rw-r-- 1 shia 521 Oct 17 14:51 b.java
-rw-rw-r-- 1 shia 90 Oct 20 18:54 cp.awk
-rw-rw-r-- 1 shia 105 Oct 20 17:19 file.txt
I try to specific them but i don't know how to copy them.
shia#ubuntu:~/code$ ls -alxo|grep 'Oct 1[67].*java$'|awk '{print $8}'
Call.java
Overriding.java
Reuse.java
Room.java
Simpleobject.java
Static.java
Super.java
This.java
b.java
Any help,thanks a lot!
One way using find:
find . -maxdepth 1 -type f -name "*.java" -newermt 2012-10-16 ! -newermt 2012-10-18 -exec cp '{}' /home/user/dstFolder/ \;
You can use xargs to copy the files found:
...| xargs -i cp '{}' /home/user/dstFolder/
This will copy all the files found to the folder /home/user/dstFolder/.