Passing alias as argument in bash - bash

You can use built in command cal for example in this way:
cal 10 2013
and you will get a calendar of Octber 2013. My teacher made and assignment to change first argument in a way, that we could call this function in our native language. For example:
cal spalis 2013
cal gruodis 1999
and so on..
(spalis means october, and gruodis -december in my country)
And we would see same result as cal 10 2013 or cal gruodis 1999
Same goes with others months. I am newbie in shell, and thought that i could make an alias:
alias spalis=10
and then i tried to use cal spalis 2013, but i got error:
cal: spalis is neither a month number (1..12) nor a name
So, after googling for a while, i guess there is no way to pass alias as an argument? Or i'am doing something wrong? Maybe there is some other way? I'll be very thankful for an advice and sorry for bad english :)

Aliases only work for the command name, not for arguments. What you'll want to do is write a function cal which replaces the first argument with the appropriate number and then calls the regular cal binary.
cal() {
local month=$1
local year=$2
# replace named $month with a numeric $month here
...
# Call the real cal. `command' ignores this function and calls the underlying binary.
command cal "$month" "$year"
}

cal accepts month names in the language specified by the current locale. To accept Lithuanian month names, use
$ LANG=lt_LT cal spalis 2013
Spalio 2013
Sk Pr An Tr Kt Pn Št
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
This depends on the version of cal you are using. The above works on my MacOS X 10.9 machine, but not on one of my Linux boxes (where cal doesn't accept month names at all, only numbers).
This may not be exactly what your teacher is looking for, as it only requires using the program as intended. :)

Related

How to perform date operations in bash

Basically, I want to take a time, and day of the week, in UTC+8, and adjust the datetime object to a given UTC offset, within bash, I don't have any code to show because I'm not sure how to start attempting this in the first place honestly
(I'm writing a custom script for a friend who lives in UTC+8 and want to make the input as easy as possible for them, basically they just give it a time in their timezone, and a day of the week, and it'll tell them what date and time that'll be in a different timezone, for an overarching purpose)
For a reference, look at the section 1 of the manual page for "date":
In your shell, just type: man 1 date
or see the online man page:
https://man7.org/linux/man-pages/man1/date.1.html
One way is to parse the date into the number of seconds since epoch (since 1970), and then convert that number of seconds into the format you want:
For example:
$ date +%s --date='2022-12-27 11:30:17 +008'
1672140137
$ date +%c --date='#1672140137'
Tue 27 Dec 2022 06:22:17 AM EST
or you could also convert to ISO format then back to local time
$ date -Iseconds --date='TZ="GMT" 2022-12-22 11:33:44 +08'
2022-12-21T22:33:44-05:00
$ date --date='2022-12-21T22:33:44-05:00'
Wed 21 Dec 2022 10:33:44 PM EST
I hope this helps you get started with some ideas for converting to/from different timezones.
Also, to help with user input, you can show the current month calendar using cal
$ cal
December 2022
Su Mo Tu We Th Fr Sa
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
$ date --date='Fri 08:30'
Fri 30 Dec 2022 08:30:00 AM EST
In the above example, I specified "Fri 08:30" which gets set to the next Friday at 08:30 in the morning for my local timezone.

ValidationException: Parameter ScheduleExpression is not valid

My cron syntax is
cron(25 8 10 2 4 2022)
And I wish to run the job exactly once on Thursday February 10 at 8:25 am. But getting the above error when trying to run.
You can schedule lambda event using following syntax:
# NOTE: This will execute on UTC mode only
cron(Minutes Hours Day-of-month Month Day-of-week Year)
So your cron expression should look like:
cron(25 08 10 02 ? 2022)
For more information, here is the official AWS Guide

Automating a roster with bash

I have to create a cleaning roster for an appartment building and would like to automate it with GNU bash if possible.
Requirements:
The tenants have to clean the corridor on their floor every week.
The cycle starts on Feb. 11, 2019 and lasts for 30 weeks (10x3).
There are 4 floors to my building.
There are 10 tenants capable of doing the task per floor.
The names of the tenants are in the 3rd column of the file tenants.csv, (sep = |).
The 1st column contains the appartment number which if it starts with a 2, such as in 214 means they are located on Floor number 2.
I would like to generate the dates automatically (maybe from the Date command with the week number %V which is starting on mondays) and merge in the names of the tenants from the csv file. Use of the date command and %V is way more complicated than I am used to. I don't know how to tackle this.
Desired Output (sample taken from the 2018 roster):
Week of Floor 1 Floor 2 Floor 3 Floor 4
Sep 18, Nov 27, Feb 5 Ms.X Mr.Y Ms.XX Mr.YY
Sep 25, Dec 4, Feb 19 Ms.AA Ms.BB Mr.CC Mrs.DD
...
So far, I have only this as the displaying (which i can handle i think) depends how i get the date command to give me the proper dates:
roster_start=$(date -d "20190211") # 11 fev 2019 start of cleaning roster
yr=2019; wk=6
date -d "Feb 6 $yr" +%V
date -d "20190211"
printf "\nWeek of\tFloor 1\t\tFloor 2\t\tFloor 3\t\tFloor 4\n"; \
for wk in 6 16 26 "$yr"; do
printf "%s\t" "$d"
date -d "$wk" +"%b %e"
done
Thank you for any help you can provide.

Deriving URLs from date

I would like to automate a download of an image from a third party server with a CRON job and then upload the image to my website.
I have 2 issues:
First, the third party site changes the image name every day using the following logic:
http://thirdpartysite.com/ImageFinder.aspx?ReportID=FILENAME
where FILENAME is 26601 +14 for each day after 6 Oct 2014 (so 7 Oct would be 26615, 8 Oct would be 26629 etc).
How do I build this into a simple Linux bash script for use with wget?
Second, how do I upload this to my site via FTP (or similar) with the same script.
NOTE: I have permission to host the file on my site and have linked the original site / placed credit for the image.
Following the suggestions of #Abhay, first get the timestamp of Oct 6, let's store it in the variable $d0:
d0=$(date +%s -d 20141006)
Then store the timestamp of a target date, say Oct 8 and store it in $d1:
d1=$(date +%s -d 20141008)
Then you can calculate the difference and apply the required arithmetic operations in $((...)), like this:
echo $((26601 + 14 * (d1 - d0) / 60 / 60 / 24))
# outputs: 26629
The date command has one very good format: %s, which prints number of seconds since "epoch", which is the fixed date 1 January 1970, 00:00 UTC. I'll call it "timestamp". In combination with this, you can use the -d date-string, so that it prints the given date as number of seconds. Now you can take today's timestamp, subtract the timestamp of "6 Oct 2014" from it, and you get number of seconds between the two times. Now you can divide it by (60 * 60 * 24) to get it in number of days, and do further arithmetic to get the desired number, and make a file name out of it.
The date string formats that -d option takes are flexible, but as of now I am not sure whether it takes "6 Oct 2014" as is. Try a few permutations, or better, check the "info" page.

Convert Julian Timestamp to Regular Time in UNIX

I need to convert Julian timestamp to Regular timestamp in UNIX using Bash.
On Tandem OS, conversion is pretty straightforward -
Example:
212186319010244541
$OLSAPP SYSTST 1> #interprettimestamp 212186319010244541
#interprettimestamp 212186319010244541 expanded to:
2455860 2011 10 25 16 10 10 244 541
I wish to do the same on UNIX environment. The conversion will be a part of a parser script. So one-liners would be greatly appreciated.
UPDATE:
INTERPRETTIMESTAMP inbuilt function on Tandem returns a space-separated list of nine numbers, consisting of the Julian day number, year, month, day, hour, minute, second, millisecond, and microsecond.
Assuming the number is as #blahdiblah says
"a value representing the number of microseconds since January 1, 4713 B.C."
Then you first need to know the Julian timestamp for 01-JAN-1970 which is the epoch for unix time. So a cludgy oracle query gives
210866803200000000
Then you could in theory just have a shell command to compute the number of seconds since 1-Jan-1970.
unixtime=$(( ( 212186319010244541 - 210866803200000000 ) / 1000000 ))
The problems with this are:
you still need to format it
your bash may not like integer arithmatic with 18 digit numbers. (think its OK in 64 bit, but not 32 bit).
Now if you have perl installed you can solve these using the bigint and POSIX modules. As a shell "one" liner it looks like
perl -mbigint -mPOSIX -e 'print( POSIX::strftime("%Y-%m-%d %T",localtime( ($ARGV[0]-210866803200000000)/1000000 ) )."\n")' 212186319010244541
Which gives
2011-10-25 15:10:10
The 1 hour difference is probably due to daylight savings differences. It could be either in the perl, or more likely the value I used for 01-Jan-1970 could be an hour out. So you may need to check both of them to be sure its right for your system.
this is MJD converter
MJD is -3506716800 than epoch
# date -d '1858-11-17 UTC' +%s
-3506716800
example:
MDJ 57153 is Mon May 11 00:00:00 UTC 2015
# date -d #`echo 57153*86400-3506716800|bc`
Mon May 11 00:00:00 UTC 2015

Resources