본문 바로가기
리눅스 (Linux)

연월 입력받아 달력 출력하기

by 멸치김밥 2021. 12. 21.

https://blog.naver.com/PostView.nhn?blogId=92wldns&logNo=220772177651 

 

[리눅스 Shell과제] 우분투에서 Shell파일로 만년달력 만들기

1. 소스 코딩2. 실행 결과(월)3. 실행 결과(년)

blog.naver.com

위 블로그 글을 참고하여

연, 월을 전달인자로 넣으면 그 연도와 월에 해당하는 달력을 출력하는 쉘 스크립트 파일을 만들었다.

 


  • 전체 코드

https://github.com/LeessangMin/Linux_study/blob/main/calendar/calendar.sh

 

GitHub - LeessangMin/Linux_study

Contribute to LeessangMin/Linux_study development by creating an account on GitHub.

github.com

 

  • 결과
$ ./calendar.sh [연] [월]
$ ./calendar.sh 1900 1

          1900년 01월
일   월   화   수   목   금   토
================================
      1    2    3    4    5    6   
 7    8    9   10   11   12   13   
14   15   16   17   18   19   20   
21   22   23   24   25   26   27   
28   29   30   31

 

  • 코드 해석
min_year=1900
max_year=2200
days=0
#   월  1  2  3  4  5  6  7  8  9 10 11 12
month=(31 28 31 30 31 30 31 31 30 31 30 31)
monthInput=$2
monthOutput=0

if [ $monthInput -lt 10 ]; then
    monthOutput=0$monthInput
else
    monthOutput=$monthInput
fi
............................................

연(년)의 최소값이자 기준이 될 변수인 min_year 에 1900을 넣었다.

days는 0으로 두고 입력된 연, 월에 따라 그만큼 일수로 계산해 더해줄 예정

month는 각 월에 해당하는 일수를 배열로 담아둔다.

monthInput, monthOutput은 그냥 달력에 표기될 월을 "1월" 에서 "01월" 같이 표기할 용도

조건문을 통해 1~9월인 일의자리수 앞에 0을 넣어준다

 

................................................
# 입력한 연도와 월이 문제가 없는지 거르기
if [ $1 -lt $min_year ] || [ $1 -gt 2200 ]; then
    echo "연도는 1900~2200 값을 입력하세요"
elif [ $2 -ge 13 ] || [ $2 -lt 1 ]; then
    echo "월은 1~12 값을 입력하세요"
else
................................................

입력받는 연, 월의 제한을 두기 위해 

연는 1900~2200까지, 월은 1~12까지로 벗어난 값을 입력하면 각 메시지를 출력하고 끝내기

 

 

..........................................................................
    # ▼ 시작연도(1900년)부터 입력한 연도까지 차이만큼 일수 계산하기 ▼
    # 시작연도가 입력한 연도보다 작으면 반복실행
    while [ $min_year -lt $1 ]; do
        # ▼ 1년을 윤년은 366일, 평년은 365일로 만들기 위해 조건문 만들기 ▼
        # 4로 나눠떨어지면(나머지가 0이면) 윤년임
        if [ $(expr $1 % 4) -eq 0 ]; then
            # 그중 400으로 나눠떨어지면 윤년,
            if [ $(expr $1 % 400) -eq 0 ]; then
                days=$(expr $days + 366)
            # 100으로 나눠떨어지면 평년
            elif [ $(expr $1 % 100) -eq 0 ]; then
                days=$(expr $days + 365)
            # 4로 나눠떨어지고 400,100이랑 관계없는 나머지 윤년들
            else
                days=$(expr $days + 366)
            fi
        # 평년
        else
            days=$(expr $days + 365)
        fi
        # 1년치 일수 계산 끝났으면 시작연도 +1
        min_year=$(expr $min_year + 1)
    done
..........................................................................

기준일인 1900년부터 입력한 연도까지 1년씩 올라가며 평년이면 365일, 윤년이면 366일을 days에 더해준다

 

..............................................
    # ▼ 윤년이면 2월을 29일로 바꿔주기 ▼
    if [ $(expr $1 % 4) -eq 0 ]; then
        if [ $(expr $1 % 400) -eq 0 ]; then
            month[1]=29
        elif [ $(expr $1 % 100) -eq 0 ]; then
            month[1]=28
        else
            month[1]=29
        fi
    else
        month[1]=28
    fi
..............................................

윤년 366일 계산한것과 같이 윤년이면 month 배열에서 2월 자리에 29를 넣도록 만들어준다

 

 

...................................................................
    # ▼ 입력한 월이 시작월인 1월보다 크면 차이만큼 일수로 계산하기 ▼
    while [ $monthInput -gt 1 ]; do
        # 총 일수에 입력한 월에 해당하는 일수 더하기
        days=$(expr $days + ${month[$monthInput - 2]})
        # 입력한 월에서 1월까지 가기 위해 1씩 빼주기
        monthInput=$(expr $monthInput - 1)
    done
...................................................................

 입력한 월에서부터 1월까지 거슬러올라가며 각 월에 해당하는 일수만큼 days에 더해준다

 

 

..............................................................
    # 달력 틀 출력
    echo
    echo "          $1년  $monthOutput월"
    echo "일   월   화   수   목   금   토"
    echo "================================"
..............................................................

출력될 달력의 틀을 만들어놓고 

 

 

..............................................................
    # 일 출력할 때 요일에 따라 공백과 줄바꿈을 만들기 위한 변수
    dayAndBlank=$(expr $days + 1)
    dayAndBlank=$(expr $dayAndBlank % 7)

    blankTemp=0
    # 해당 월의 1일부터 출력을 시작하기위해 공백 넣기
    while [ $blankTemp -lt $dayAndBlank ]; do
		# echo가 끝나면 줄바꿈을 하는데 -n을 넣으면 줄바꿈을 하지 않는다
		echo -n "     "
        blankTemp=$(expr $blankTemp + 1)
    done
..............................................................

1900년부터 입력한 연도의 차이나는 일수와 1월부터 입력한 달까지의 차이나는 일수를 합한 값이 담긴 변수

days를 7(일주일)로 나눈 나머지를 가지고 0~6회 빈칸을 넣어주면

해당 연월에 1일로 시작할 위치까지 빈칸으로 채우게 된다

 

 

...........................................................................................
    dayTemp=1
    # 1일부터 해당 월의 마지막날까지 1씩 더해가며 출력하기
    while [ $dayTemp -le ${month[$2 - 1]} ]; do
        # 토요일에서 일요일로 넘어가면 한줄 내리기 && 처음부터 0이면 달력 첫줄이 통으로 빈줄이 되는것 방지
        if [ $(expr $dayAndBlank % 7) -eq 0 ] && [ ! $dayAndBlank -eq 0 ]; then
            echo
        fi
        # 이번 출력할 일자가 십의자리수면
        if [ $dayTemp -ge 10 ]; then
            # 공백 없이,
            echo -n "$dayTemp"
        else
            # 일의자리면 앞에 공백 한개 주기
            echo -n " $dayTemp"
        fi
        # 다음요일 칸으로 가기 위한 공백 출력
        echo -n "   "
        # 다음날로 만들기 위해 +1
        dayTemp=$(expr $dayTemp + 1)
        dayAndBlank=$(expr $dayAndBlank + 1)
    done
    echo
fi

그리고 dayTemp로 1일부터 그달 마지막일까지 출력하며

토요일까지 출력하면(dayAndBlank % 7 이 0이 될때) 다음줄로 내려준다.

if [ $(expr $dayAndBlank % 7) -eq 0 ] && [ ! $dayAndBlank -eq 0 ]; then

이부분은 월의 1일 시작이 일요일일 경우(dayAndBlank=0) 달력의 첫줄부터 줄바꿈을 하고 시작되지 않게 하기 위해 추가했다.

 

 

이제 쉘 스크립트 파일을 연도와 월을 넣어 실행시키면

$ ./calendar.sh 2021 12

시꺼먼 달력이 완성된다

'리눅스 (Linux)' 카테고리의 다른 글

IF 와 CASE  (0) 2021.12.21
비교 연산자  (0) 2021.12.21
배열  (0) 2021.12.20
리다이렉션  (0) 2021.12.19
명령어 치환 (Command Substitution)  (0) 2021.12.19

댓글