Is it possible to fetch 5th and/or 6th day of every month in Unix?
I've tried this but it does not give me the desired output:
echo $((($(date +%-d)-1)/5))
Use this:
for month in {1..12}; do date -d "$month/5/2017" +"%c - is a %A"; done
Output:
Thu 05 Jan 2017 12:00:00 AM CET - is a Thursday
Sun 05 Feb 2017 12:00:00 AM CET - is a Sunday
Sun 05 Mar 2017 12:00:00 AM CET - is a Sunday
Wed 05 Apr 2017 12:00:00 AM CEST - is a Wednesday
Fri 05 May 2017 12:00:00 AM CEST - is a Friday
Mon 05 Jun 2017 12:00:00 AM CEST - is a Monday
Wed 05 Jul 2017 12:00:00 AM CEST - is a Wednesday
Sat 05 Aug 2017 12:00:00 AM CEST - is a Saturday
Tue 05 Sep 2017 12:00:00 AM CEST - is a Tuesday
Thu 05 Oct 2017 12:00:00 AM CEST - is a Thursday
Sun 05 Nov 2017 12:00:00 AM CET - is a Sunday
Tue 05 Dec 2017 12:00:00 AM CET - is a Tuesday
For the 6th of the month, it's done in a similar way.
I am not sure if this is what you are looking for: i am assuming you want to get the 5th(or 6th) day of a month sitting on any day. If so, you can make use of the current date and get the 5th day of current month like below:
dd=`date '+%d'`
if(( $dd > 5 )); then
(( diff = dd - 5 ))
myDate=`date -d "-$diff days"`
else
(( diff = 5 - dd ))
myDate=`date -d "+$diff days"`
fi
echo $myDate
For 6th day you can do similarly. Above code should work on Linux distro.
Related
I wanted to construct a spring cron expression that executes At 23:00:00pm, on first Sunday, every 2 months starting in January, so far I have this
0 0 23 ? 1/2 SUN but this one executes At 23:00:00pm, every Sunday, every 2 months starting in January. how can I make it execute only the first Sunday every two months?
0 0 23 ? 1/2 SUN next excution dates are as follows
Sun Mar 07 23:00:00 UTC 2021
Sun Mar 14 23:00:00 UTC 2021
Sun Mar 21 23:00:00 UTC 2021
Sun Mar 28 23:00:00 UTC 2021
Sun May 02 23:00:00 UTC 2021
Sun May 09 23:00:00 UTC 2021
Sun May 16 23:00:00 UTC 2021
Sun May 23 23:00:00 UTC 2021
Sun May 30 23:00:00 UTC 2021
Sun Jul 04 23:00:00 UTC 2021
but what I wanted was
Sun Mar 07 23:00:00 UTC 2021
Sun May 02 23:00:00 UTC 2021
Sun Jul 04 23:00:00 UTC 2021
how can I improve my expression to get the above result?
0 0 23 1-7 1/2 SUN
The only part you are missing, is day number in the range 1-7.
Code to verify the schedule:
var sundays = CronExpression.parse("0 0 23 1-7 1/2 SUN");
var nextDate = LocalDateTime.now();
var dateFormatter = DateTimeFormatter.ofPattern("EEE, MMM d, yyyy 'at' hh:mm:ss a");
for (var i = 0; i < 10; i++) {
nextDate = sundays.next(nextDate);
System.out.println(nextDate.format(dateFormatter));
}
Will run at:
Sun, Mar 7, 2021 at 11:00:00 pm
Sun, May 2, 2021 at 11:00:00 pm
Sun, Jul 4, 2021 at 11:00:00 pm
Sun, Sep 5, 2021 at 11:00:00 pm
Sun, Nov 7, 2021 at 11:00:00 pm
...
I want to automate a task quarterly in a year.
Task should execute
Jan 1st
April 1st
July 1st
October 1st
etc
As I tried #Scheduled(cron = "0 0 6 1 1/3 ?") in Spring Boot application but its not working currently and mail didn't trigger quarterly.
Try this
#scheduled(cron = "0 0 6 1 */3 *")
So read the first day of each 3 month at 6:00
Try this one -
#scheduled(cron ="0 0 0 1 JAN,APR,JUL,OCT ? *")
Next execution:
Wed Jul 01 00:00:00 UTC 2020
Thu Oct 01 00:00:00 UTC 2020
Fri Jan 01 00:00:00 UTC 2021
Thu Apr 01 00:00:00 UTC 2021
Thu Jul 01 00:00:00 UTC 2021
Fri Oct 01 00:00:00 UTC 2021
Sat Jan 01 00:00:00 UTC 2022
Fri Apr 01 00:00:00 UTC 2022
Fri Jul 01 00:00:00 UTC 2022
Sat Oct 01 00:00:00 UTC 2022
I have a list of files with the substring YYYYMMDDHH in them (example: 2016112200 means 2016 November 22th at 00 hours). These files are: temp_2016102200.data, temp_2016102212.data, temp_2016102300.data, temp_2016102312.data, ..., temp_20170301.data. And I also have other family of files substituting temp by wind.
For each string YYYYMMDDHH I want to create a tar with the temp and its correspondent wind file. I don't want this process to stop if one or both files are missing.
My idea was to loop from 12 hours to 12 hours, but I am having some problems because to specify the date I did: b=$(date -d '2016111400' +'%Y%m%d%H') but bash informs me that that is not a valid date...
Thanks.
It's not bash telling you the date format is wrong: date is telling you. Not everything you type is a bash command.
As Kamil comments, you have to split it up so that date can parse it. The YYYY-mm-dd HH:MM:SS format is parsable. Using bash parameter expansion to extract the relevant substrings:
$ d=2016111400
$ date -d "${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00"
Mon Nov 14 00:00:00 EST 2016
Now, when you want to add 12 hours, you have to be careful to do it in the right place in the datetime string: if you add a + character after the time, it will be parsed as a timezone offset, so put the relative part either first or between the date and the time.
$ date -d "+12 hours ${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00"
Mon Nov 14 12:00:00 EST 2016
As a loop, you could do:
d=2016111400
for ((i=1; i<=10; i++)); do
# print this datetime
date -d "${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00"
# add 12 hours
d=$( date -d "+12 hours ${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00" "+%Y%m%d%H" )
done
outputs:
Mon Nov 14 00:00:00 EST 2016
Mon Nov 14 12:00:00 EST 2016
Tue Nov 15 00:00:00 EST 2016
Tue Nov 15 12:00:00 EST 2016
Wed Nov 16 00:00:00 EST 2016
Wed Nov 16 12:00:00 EST 2016
Thu Nov 17 00:00:00 EST 2016
Thu Nov 17 12:00:00 EST 2016
Fri Nov 18 00:00:00 EST 2016
Fri Nov 18 12:00:00 EST 2016
OK, a "nicer" way to loop
start=2019043000
end=2019050300
plus12hours() {
local d=$1
date -d "+12 hours ${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00" "+%Y%m%d%H"
}
for (( d = start; d <= end; d = $(plus12hours "$d") )); do
printf "%d\t%s\n" "$d" "$(date -d "${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00")"
done
2019043000 Tue Apr 30 00:00:00 EDT 2019
2019043012 Tue Apr 30 12:00:00 EDT 2019
2019050100 Wed May 1 00:00:00 EDT 2019
2019050112 Wed May 1 12:00:00 EDT 2019
2019050200 Thu May 2 00:00:00 EDT 2019
2019050212 Thu May 2 12:00:00 EDT 2019
2019050300 Fri May 3 00:00:00 EDT 2019
DateTime#parse on 'Mon, 30 Dec 2013 00:00:00 UTC +00:00' is wrong for the week. I chose ISO 8601 week-based year and week number %V (week number 01..53 of the week-based year).
With format "%V-%y":
DateTime.parse('Mon, 30 Dec 2013 00:00:00 UTC +00:00').strftime "%V-%y"
#⇒ "01-13"
DateTime.parse('Mon, 30 Dec 2013 00:00:00 UTC +00:00').strftime "%W-%y"
#⇒ "52-13"
Date.strptime('01-13', '%V-%y')
#⇒ Tue, 01 Jan 2013
Date.strptime('52-13', '%V-%y')
#⇒ Tue, 01 Jan 2013
Mon, 30 Dec 2013 00:00:00 UTC +00:00 is not "01-13".
But if I use "%W" format, the result is correct ("52-13").
What is it? Or did I make some mistakes?
With week-based week number (%V) one should use week-based year (%g):
DateTime.parse('Mon, 30 Dec 2013 00:00:00 UTC +00:00').strftime "%V-%g"
#⇒ "01-14"
The cday, cweek and cyear are the methods based on the commercial dates.
commercial: Creates a date object denoting the given week date.
So, the last days of an year can be the same week to the new year's starting days. For example 2013 december last dates and 2014 Jan starting days are of the same week, so the week number of the date 'Mon, 30 Dec 2013 00:00:00 UTC +00:00' comes to the new week of next year after all the weeks of the year are completed.
So,
"Mon, 30 Dec 2013 00:00:00 UTC +00:00".to_date.cweek ==> 1
"Mon, 30 Dec 2013 00:00:00 UTC +00:00".to_date.cwday ==>1 (1st week day of week 1 2014(but date is still of 2013)
"Mon, 30 Dec 2013 00:00:00 UTC +00:00".to_date.cwyear ==> 2014
Those are commercial dates, Now check,
"Mon, 30 Dec 2013 00:00:00 UTC +00:00".to_date.year ==> 2013
This is Normal year.
This has a perfect example
Right now, I am running the following command:
rpm -qa --queryformat '%{name}\t%{installtime:date}\n' | sort -nr
and getting some output like this:
dhclient Fri 07 Feb 2014 01:37:47 PM EST
device-mapper-persistent-data Fri 07 Feb 2014 01:27:37 PM EST
device-mapper-libs Fri 07 Feb 2014 01:34:44 PM EST
device-mapper Fri 07 Feb 2014 01:34:46 PM EST
device-mapper-event-libs Fri 07 Feb 2014 01:34:48 PM EST
device-mapper-event Fri 07 Feb 2014 01:34:50 PM EST
dbus-libs Fri 07 Feb 2014 01:25:28 PM EST
dbus-glib Fri 07 Feb 2014 01:33:48 PM EST
db4-utils Fri 07 Feb 2014 01:30:05 PM EST
db4 Fri 07 Feb 2014 01:24:58 PM EST
dash Fri 07 Feb 2014 01:30:19 PM EST
cyrus-sasl-lib Fri 07 Feb 2014 01:25:48 PM EST
(note the odd tabs)
How do I tell the command I want it to output it into a table with common spacing instead of specifying the number of tabs?
Extra Question:
What I'm trying to do is just find out what has been installed and when so I can uninstall everything that I installed recently. How do I do that better than what I'm doing?
rpm -qa --queryformat '%-40{name} %{installtime:date}\n' | sort -nr
^^^
This will left-align the name and pad it to 40 characters.
If you want to order by time, you could print the numeric time first so it's easy to sort by.
$ rpm -qa --queryformat '%-10{installtime} %{installtime:date} %{name}\n' | sort -n
...
1375369678 Thu 01 Aug 2013 11:07:58 AM EDT xorg-x11-util-macros
1375886901 Wed 07 Aug 2013 10:48:21 AM EDT libdc1394
1378148462 Mon 02 Sep 2013 03:01:02 PM EDT gnome-system-monitor
1384526666 Fri 15 Nov 2013 09:44:26 AM EST perl-File-Next
1384526667 Fri 15 Nov 2013 09:44:27 AM EST ack
1385065567 Thu 21 Nov 2013 03:26:07 PM EST trousers
1385065568 Thu 21 Nov 2013 03:26:08 PM EST tpm-tools
1387405750 Wed 18 Dec 2013 05:29:10 PM EST libusb1