Multi-Parameter Curly Brace Expansion in Bash - bash

How can I use brace-expansion to make the equivalent of cal 8 2014; cal 9 2014? cal {8,9} 2014 expands to cal 8 9 2014 (showing the 9th of September.) cal {08 2014,09 2014} isn't a valid brace expansion, and I can't use cal {"08 2014","09 2014"} because that expands to cal "08 2014" "09 2014" which is two parameters that obviously don't make sense together here :/ I'm starting to question the utility of brace expansion....

brace-expansion is great, for loops are also great, but add printf|sh to your repertoire and
you'll be in great shape:
printf "cal %s 2014\n" {8,9}|sh
One clear benefit is you can run it without |sh first to see if it looks right.
You could also escape spaces so that the brace-expansion includes cal and 2014:
$ echo cal\ {8,9}\ 2014\;
cal 8 2014; cal 9 2014;
And then pipe through sh:
$ echo cal\ {8,9}\ 2014\;|sh
August 2014
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
September 2014
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

Related

Why doesn't the output of the command `cal` have the day highlighted?

I need that the output of the command cal stay highlighted in a variable in order print it into a wallpaper so I can disable the calendar software to save resources of a low spec computer. How can I make the cal output stay highlighted?
Perhaps something like:
cal -h | sed 's/ \('"$(date +%_d)"'\) /{\1}/'
outputs
June 2021
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

Shell Script to print a calendar after the user specifies the month and a day

*****Shell Script*******
Given a month and the day of the week that's the first of that month, print a calendar for the month. (Remember, number of days in months is different and use \n to go to a new line.)
Unix has a cal command especially for this purpose.
By default, cal shows the current month's calendar.
mayankp#mayank:~/$ cal
November 2018
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
If you want a calendar for a specific month of a specific year, do this:
mayankp#mayank:~/$ cal 1 2018
January 2018
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
This displays the calendar for January 2018.
So, your shell script would be:(ex: calendar.sh)
#!/usr/bin/env bash
month=$1
year=$2
cal $1 $2
Run the script like this:
mayankp#mayank:~/$ sh calendar.sh 3 2018
March 2018
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
Let me know if this helps.

Get next month in terminal

In OSX on the terminal, how can cal be used to obtain the calendar of the next month?
i.e. the following
command: "cal -m && date +%m +1"
should equate to
command: "cal -m 7"
and produce:
July 2014
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
Use this:
m=$(date +'%m'); ((m++)) ; cal -m $m
or this:
cal $(date -v+1m +'%m %y')

Script for counting weekends

Script for counting weekends (saturdays AND sundays) in a given month, by passing in month and year. How to write it?
New in scripting, can't find solution to this easy task.
You want to count weekends Sat and Sun, So I am guessing you mean 2 day weekends.
Hope this helps. VonBell
In unix/linux you can easily parse the cal command for the given month.
$ cal 04 2013
April 2013
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
The numerical date always start on Line 3, the cols for each day are constant
When I used the commands below to extract the weekend (sun, Sat)
As you can see Sun is cols 1,2,3 (with space included) and Sat is cols 19,20
$ cal 04 2013|tail +3|cut -c1-3,19,20
.. 6
7 13
14 20
21 27
28
When I execute the script below as cntWkEnd.sh The output is as follows
1 equals one day wkend and 2 equals 2 day wkend sat and sun
$ ./cntWkEnd.sh 04 2013
1
2
2
2
1
0
To count only 2 day weekends you can add at the command line or in the script
the following
./cntWkEnd.sh 04 2013|grep "2"|wc -l (Output of 3 shown below)
3
This the contents of cntWkEnd.sh
#!/bin/bash
cal $1 $2|tail +3|cut -c1-3,19,20 |\
while read WkEnd
do
echo $WkEnd|wc -w
done

unix cal command special character

When I try "cal | tail -6" in my unix machine, I get -
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
but when I try "cal | tail -6 | awk '{print $7}'", I get -
10
17
24
where is 3 going ? My requirement is basically all weekdays i.e column 2,3,4,5 & 6.
But I'm getting wrong output because of the strange behavior of "cal"
There are only 3 whitespace delimited columns in your first row. cal is working exactly as corrected, you are not understanding how awk works. As far as awk is concerned there is no 7th column in your first row as it yields attention to whitespace delimited columns, not fixed width columns.
A quick google search reveals you can use
BEGIN { FIELDWIDTHS = "3 3 3 3 3 3 3" }
In your awk script.
Since all of your columns in each row are three characters wide, you could use this to extract the days you wish for. For example, if you wanted only the 7th day in a column, you could do the following:
cal | sed 's/^\(.\{18\}\).*$/\1/'
This command would remove the first 18 characters in the line, which are the entries for the first 6 days of the week.
To extract a particular day, such as the fourth day, you could do this:
cal | sed 's/^.\{9\}\(.\{3\}\).*$/\1/'
To remove the first day of the week and the last day, you could do this:
cal | sed -e 's/^.\{3\}//' -e 's/^\(.\{15\}\).\{3\}$/\1/'
May be a row-wise extraction will do the trick. Try ncal. For example:
$ ncal
November 2012
Mo 5 12 19 26
Tu 6 13 20 27
We 7 14 21 28
Th 1 8 15 22 29
Fr 2 9 16 23 30
Sa 3 10 17 24
Su 4 11 18 25
or fill the absent dates with place holder (with '-' for example):
kent$ cal -s|tail -6|awk 'NR==1&&NF<7{gsub(/^ */,"");for(i=1;i<=(7-NF);i++) x=" - "x;$0=x" "$0;}1'
- - - - 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
then you could get the column, replace '-' with " " if needed. e.g. for $7:
kent$ cal -s|tail -6|awk 'NR==1&&NF<7{gsub(/^ */,"");for(i=1;i<=(7-NF);i++) x=" - "x;$0=x" "$0;}{print $7}'
3
10
17
24
Note that todays date is highlighted unless you turn it off (-h). Use cut to extract the wanted columns:
cal -h | cut -c19-20
Output:
Sa
3
10
17
24

Resources