How to list only work days using shell command line on Linux

The following article will explain a simple procedure on how to list work days ( business days ) on a Linux command line. Please note that the below procedure does not take into account a public holidays for your relevant country as it simply only shows word days while excluding weekends.

For this we will be using ncal command. Let’s start the complete workout by displaying a calendar for a current month start:

$ ncal -h
    August 2016       
Mo  1  8 15 22 29   
Tu  2  9 16 23 30   
We  3 10 17 24 31   
Th  4 11 18 25      
Fr  5 12 19 26      
Sa  6 13 20 27      
Su  7 14 21 28 

Next, we need to extract only work days from the calendar, while also removing all unnecessary data such as empty lines and month headings:

$ ncal -h | grep -vE "^S|^ |^$" 
Mo  1  8 15 22 29   
Tu  2  9 16 23 30   
We  3 10 17 24 31   
Th  4 11 18 25      
Fr  5 12 19 26 

At this stage we also remove all alphabetic characters:

$ ncal -h | grep -vE "^S|^ |^$" | sed "s/[[:alpha:]]//g" 
  1  8 15 22 29   
  2  9 16 23 30   
  3 10 17 24 31   
  4 11 18 25      
  5 12 19 26

The above integers are all work days for a current month. Let’s format and sort them:

$ ncal -h | grep -vE "^S|^ |^$" | sed "s/[[:alpha:]]//g" | fmt -w 1 | sort -n
  1
  2
  3
  4
  5
  8
  9
  10
  11
  12
  15
  16
  17
  18
  19
  22
  23
  24
  25
  26
  29
  30
  31

That is all. Now, you have a complete and sorted list of all work days for a current month. In case you wish to calculate the number of work days for a current month simply pipe the output to wc command:

$ ncal -h | grep -vE "^S|^ |^$" | sed "s/[[:alpha:]]//g" | fmt -w 1 | sort -n | wc -l
23

That was easy. If you wish to know the number of work days for an entire year eg.2017 add your desired year as ncal argument:

$ ncal -h 2017 | grep -vE "^S|^ |^$" | sed "s/[[:alpha:]]//g" | fmt -w 1 | sort -n | wc -l
260

From here we can easily use bash for loop and calculate the number of your work days between range of years. As for an example the next 40 years between 2017 – 2047:

 $ for i in $( seq 2017 2047 ); do ncal -h $i | grep -vE "^S|^ |^$" | sed "s/[[:alpha:]]//g" | fmt -w 1 | sort -n | wc -l; done | paste -sd+ - | bc
8087

You just witnessed the power of GNU/Linux shell.



Comments and Discussions
Linux Forum