기록/리눅스
[리눅스] 쉘 스크립트 실습 - 연도와 월을 입력 받아 달력 출력하기
코드코코
2021. 12. 21. 21:41
실습
연도와 월을 입력 받아 달력 출력하기
윤년규칙
1) 4년으로 나누어지는 해는 윤달(2월 29일)이 있다.
2) 100년으로 나누어지는 해는 윤달이 없다.
3) 400년으로 나누어지는 해는 윤달이 있다.
4) 위 규칙들을 만족해야만 그 해가 윤년(2월 29일)이고 아닌 경우에는 평년(2월 28일)이다.
작성내용
#!/bin/bash
while [ ture ] # 무한루프 실행
do # 무한루프 while 시작
startyear=1900 # 1900년으로 초기화
lastday=(31 28 31 30 31 30 31 31 30 31 30 31) # 각 월의 마지막 날을 저장하는 배열 (윤년을 뺀 기준으로)
sum=0 #1900년부터 사용자가 입력한 년도까지의 디데이를 담아줄 변수
echo -e "Enter year, month ex) 2019 10" # 사용자에게 입력형식을 알려준다
read year month # 사용자가 원하는 년도와 달을 입력
while [ $startyear -lt $year ] #1900년도부터 사용자가 입력한 년도까지 반복 – 윤년을 포함한 디데이를 세는 반복문
do
if [ `expr $startyear % 4` -eq 0 ] # startyear가 4로 나눠지고,
then
if [ `expr $startyear % 400` -eq 0 ] # 400으로도 나눠지면 이는 윤년이므로 일년 즉, 365일에 1을 더한
then
sum=`expr $sum + 366` #366일을 더한다
elif [ `expr $startyear % 100` -eq 0 ] # 4로 나누어지지만 100으로도 나누어진다면 윤년이 아니므로
then
sum=`expr $sum + 365` # 평년인 365일을 더한다
else
sum=`expr $sum + 366` # 100으로 나눠지지 않는다면 윤년이므로 366일을 더해준다
fi
else
sum=`expr $sum + 365` # 4로 나눠지지 않는다면 평년이므로 365일을 더한다
fi
startyear=`expr $startyear + 1` # 입력한 년도까지의 일 수를 구하기 위해 1900년부터 더해준다
done
if [ `expr $year % 4` -eq 0 ] # 2월달의 마지막 날 재정의
then
if [ `expr $year % 400` -eq 0 ] # 윤년일 때 2월의 마지막 날을 29일로 변경해준다
then
lastday[1]=29 # lastday[1]인 이유는 인덱스가 0부터 시작해 두 번째 배열의 인덱스 값은 0이기 때문
elif [ `expr $year % 100` -eq 0 ]
then
lastday[1]=28 # 평년일 시 2월의 마지막 날을 28로 정의해준다
else
lastday[1]=29 # 100으로 나눠지지 않는다면 이는 윤년이므로 2월달의 마지막 날을 29일까지로 변경
fi
else
month[1]=28 #그 외의 평년 2월달은 28일로 정의해준다
fi
i=0 # 달의 일수가 저장된 month의 배열 인덱스로 사용 할 변수 I 초기화
while [ $i -lt `expr $month - 1` ] # 0부터 입력받은 달 – 1 로 반복한다
do
sum=`expr $sum + ${lastday[$i]}` # 10월달의 달력을 보고싶다면 9월달까지의 일 수를 알아야하므로 month – 1로 반복
i=`expr $i + 1` # 배열 인덱스를 하나씩 올려주며 값을 사용자가 원하는 최종 달의 일 수를 구한다
done
echo -e "\t\t$year $month\n" # N년 M월
echo -e "SUN\tMON\tTUS\tWED\tTHU\tFRI\tSAT\n"
echo -e "===================================================\n"
# 일(0) 월(1) 화(2) 수(3) 목(4) 금(5) 토(6)
cnt=`expr $sum + 1` # 요일을 알기위한 변수로 1900년 1월 1일은 월요일로 시작하기 때문에 1을 더해준다
cnt=`expr $sum % 7` # 합계된 일 수를 7로 나누어 나머지를 구해 달의 시작 요일을 알아낸다
temp=0 # 첫 주의 1일의 요일에 맞게 공백을 넣어줄 변수를 초기화한다
while [ $temp -le $cnt ] # 첫시작위치(cnt)에 날짜가 시작될 수 있게 temp가 cnt만큼의 공백을 출력시킨다
do
if [ $cnt -eq 6 ]
then break; # 만약 달의 1일의 요일이 토(6)라면 공백이 6번 출력 되지 못하고 나가도록 제어문(break)을 써준다
else
echo -ne "\t" # echo의 옵션 n을 사용하여 출력 후 다음 줄로 넘어가지 못하게 한다
fi
temp=`expr $temp + 1` # 반복문의 변수(temp)를 하나씩 올려주며 공백을 출력한다
done #공백 출력 반복문 종료
cnt=`expr $cnt + 1` # 공백 출력 후 날 입력을 위해 공백 출력 다음 1을 해준다
day=1 # 달은 1일부터 시작하므로 1로 초기화 해준다
while [ $day -le ${lastday[$i]} ] # 1일부터 시작하는데 해당 월의 일 수 보다 작거나 같을때까지 반복하여 출력한다
do
echo -en "$day\t"
day=`expr $day + 1`
cnt=`expr $cnt + 1`
if [ `expr $cnt % 7` -eq 0 ] # cnt가 7이 된다면 일주일을 모두 출력한 것으로 알고
then
echo # 한줄 개행한다
cnt=0 # 시작요일(cnt)를 일요일(0)으로 초기화 시킨다
fi
done #날짜 출력 반복문 종료
echo
done
실행결과
- 2020 2월 출력(윤달)
