本月最后一个工作日

本月最后一个工作日
#!/bin/bash
#!/usr/local/bin
#!/usr/sbin
#!/usr/bin
# Script to Check last working Day of the Month

echo " Enter Month and Year :"
read mon year
cal $mon $year| egrep  "28|29|30|31"|awk 'BEGIN {
        var1=$NF;var2=NF;
        }
        {
        if (NF > 1 &&  NF < 7)
                val=$NF;
        else if (NF == 1)
                val=$NF-2;
        else if (NF == 7)
                val=$NF-1;
        }
        {
                print "Last Working Date is : " val;
        }'

脚本输出:

511@ubuntu:~/Unix$ ./test.sh
 Enter Month and Year :
4 2015
Last Working Date is : 30
511@ubuntu:~/Unix$ ./test.sh
 Enter Month and Year :
5 2015
Last Working Date is : 29
Last Working Date is : 29
511@ubuntu:~/Unix$ ./test.sh
 Enter Month and Year :
7 2015
Last Working Date is : 31
511@ubuntu:~/Unix$ ./test.sh
 Enter Month and Year :
1 2015
Last Working Date is : 30

为什么当我们给出如下输入时脚本会打印两次:

511@ubuntu:~/Unix$ ./test.sh
 Enter Month and Year :
5 2015
Last Working Date is : 29
Last Working Date is : 29

答案1

问题是您的搜索将针对看到“28”、“29”、“30”或“31”的每一行egrep调用一次。 awk28 号在最后一个日历周之前登陆的月份将awk呼叫两次,因为有两条线路符合您的搜索条件

您希望始终使用搜索的第二行egrep,因此可以使用tail命令仅查看最后一行:

#!/bin/bash
#!/usr/local/bin
#!/usr/sbin
#!/usr/bin
# Script to Check last working Day of the Month

echo " Enter Month and Year :"
read mon year
cal $mon $year| egrep  "28|29|30|31"| tail -n 1 |awk 'BEGIN {
        var1=$NF;var2=NF;
        }
        {
        if (NF > 1 &&  NF < 7)
                val=$NF;
        else if (NF == 1)
                val=$NF-2;
        else if (NF == 7)
                val=$NF-1;
        }
        {
                print "Last Working Date is : " val;
        }'

答案2

对于日期,它只是两行 bash 计算:

#!/bin/bash

month="$1"
year="$2"

read -r dow day < <(date -d "$year/$month/1 +1 month -1 day" "+%u %d")

echo "Last working day of the month = $(( day - ( (dow>5)?(dow-5):0 ) ))"

数学计算是:如果 dow(一周中的某一天)大于 5,则从该天减去 (dow-5),否则保持该天不变。

用于:

$ ./script 2 2015
Last working day of the month = 27

答案3

ksh93

$ printf "%(%A %B %d)T\n" "October 2018 last working day"
Wednesday October 31

答案4

您的脚本重复打印,因为 awk 正在从 egrep 接收两行。但这已经在其他答案中涵盖了。

我想解释一些解决问题的替代方法,更短,更容易。

当调用 this 时,程序 cal 可以打印从星期一开始的一周(这简化了数学)cal -NMC month year。使用它:

#!/bin/bash

    lastday(){
        printf 'Last Working Date of %s/%s = ' "$1" "$2";
        cal -NMC "$1" "$2" | awk '
            /[0-9]+/{val=$( NF>5?5:NF )}
            END{ print val }'
    }

mon="$1"
year="$2"
lastday "$mon" "$year"

描述:

/[0-9]+/选择带有数字的行(避免空行)。

NF>5?5:NF数学:如果字段多于 5,则结果为 5,否则为 NF。

{val=$( ... )}选择字段的值。

END{ print val }'仅打印最后一行的值(带数字的行)。

像这样称呼它:

$ ./test.sh 4 2015
Last Working Date of 4/2015 = 30
$ ./test.sh 5 2015
Last Working Date of 5/2015 = 29
$ ./test.sh 7 2015
Last Working Date of 7/2015 = 31
$ ./test.sh 1 2015
Last Working Date of 1/2015 = 30
$ ./test.sh 9 2015
Last Working Date of 9/2015 = 30
$

相关内容