たとえば、今日は2018年6月4日で、希望の出力は2018年5月31日です。
2018年7月1日の場合、出力は2018年6月29日でなければなりません。
答え1
最後の勤務日を求め(勤務週は月曜日から金曜日までと仮定)、前月の最後の3日を降順で出力し、週末ではなく最初の日を求めます。
for m in {1..12}; do
firstMonthDay="2018-$m-01"
for i in {1..3}; do
read dow date <<<"$(date -d "$firstMonthDay - $i days" "+%u %c")"
if [[ $dow -le 5 ]]; then
echo $date
break
fi
done
done
Fri Dec 29 00:00:00 2017
Wed Jan 31 00:00:00 2018
Wed Feb 28 00:00:00 2018
Fri Mar 30 00:00:00 2018
Mon Apr 30 00:00:00 2018
Thu May 31 00:00:00 2018
Fri Jun 29 00:00:00 2018
Tue Jul 31 00:00:00 2018
Fri Aug 31 00:00:00 2018
Fri Sep 28 00:00:00 2018
Wed Oct 31 00:00:00 2018
Fri Nov 30 00:00:00 2018
私が使用した希望の出力日付形式を調整します。%c
最も繰り返しが必要な日である31日日曜日、30日土曜日、29日金曜日であるため、毎月最後の3日を使用します。
私たちはそれを関数としてカプセル化します:
lastWorkdayPreviousMonth() {
local first fmt dow date i opt OPTIND=1
while getopts :d:f: opt; do
case $opt in
d) first=$OPTARG ;;
f) fmt=$OPTARG ;;
esac
done
: ${first:=$(date "+%Y-%m-01")} ${fmt:="%c"}
for i in {1..3}; do
read dow date <<<"$(date -d "$first- $i days" "+%u $fmt")"
if [[ $dow -le 5 ]]; then
echo $date
break
fi
done
}
それから
$ lastWorkdayPreviousMonth
Thu May 31 00:00:00 2018
$ for m in {1..12}; do lastWorkdayPreviousMonth -f "%d/%m/%Y" -d 2018-$m-01; done
29/12/2017
31/01/2018
28/02/2018
30/03/2018
30/04/2018
31/05/2018
29/06/2018
31/07/2018
31/08/2018
28/09/2018
31/10/2018
30/11/2018
答え2
次の行は、前月の最後の営業日を印刷します。
day=`date -d "$(date +%m/01/%Y) -1 day" | awk '{print $1}'`; if [ $day == Sat ]; then D=`date -d "$(date +%m/01/%Y) -2 day" "+%m/%d/%Y"`;echo $D; elif [ $day == Sun ]; then D=`date -d "$(date +%m/01/%Y) -3 day" "+%m/%d/%Y"`;echo $D; else D=`date -d "$(date +%m/01/%Y) -1 day " "+%m/%d/%Y"`;echo $D; fi
ソートコード:
day=`date -d "$(date +%m/01/%Y) -1 day" | awk '{print $1}'`;
if [ $day == Sat ]; then
D=`date -d "$(date +%m/01/%Y) -2 day" "+%m/%d/%Y"`;
echo $D;
elif [ $day == Sun ]; then
D=`date -d "$(date +%m/01/%Y) -3 day" "+%m/%d/%Y"`;
echo $D;
else
D=`date -d "$(date +%m/01/%Y) -1 day " "+%m/%d/%Y"`;
echo $D;
fi