매월 마지막 근무일

매월 마지막 근무일
#!/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

문제는 egrep"28", "29", "30" 또는 "31"이 표시되는 각 행에 대해 검색이 한 번씩 호출된다는 것입니다. 검색 기준과 일치하는 두 줄이 있으므로 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 ) ))"

계산 방법은 다음과 같습니다. 다우(요일)가 5보다 크면 해당 날짜에서 (다우-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에서 두 줄을 수신하기 때문에 스크립트가 반복적으로 인쇄됩니다. 그러나 이것은 다른 답변에서 다루어졌습니다.

문제를 더 짧고 쉽게 해결할 수 있는 몇 가지 대안적인 방법을 설명하고 싶습니다.

이것이 호출되면, 프로그램 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
$

관련 정보