#!/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
调用一次。 awk
28 号在最后一个日历周之前登陆的月份将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
$