date, read -p, while 을 활용한 정합성 검사 loop 로직

2023. 12. 23. 23:09리눅스 실제 사용 팁/bash

날짜입력 후 정합성 검사

  1. 본 게시글에서는 가장 해석하기 쉬운 yyyymmdd 포맷으로 입력을 받는다.
  2. 입력된 날짜 변수값을 활용해서 전후의 날짜를 만들어내려면 입력한 날짜 데이터가 순수 숫자인지 검사해야 한다.
#!/usr/bin/bash    
    
# 숫자로만 이루어져 있는지 검사하는 패턴    
NUM_PAT='^[0-9]+$'    
    
while [ true ]    
do    
    # 날짜를 입력으로 받아서 DATE (변수) 에 저장한다.    
    read -p '원하는 날짜를 입력하세요: ' DATE    
    
    # DATE 변수값이 숫자로만 이루어졌는지 검사(변수값 =~ 패턴)    
    if ! [[ $DATE =~ $NUM_PAT ]]; then    
        echo 숫자만 입력하세요.    
    
    # '1223' 처럼 년도를 지정하지 않으면 통과시키지 않음.    
    elif [ ${#DATE} -lt 8 ]; then    
        echo 날짜가 여덟자리가 아닙니다.    
    
    # `date -d 날짜값`으로 날짜의 정합성을 검사한다.
    # (인식할 수 없을 때의 결과) date: 부적절한 날짜 `20231289'
    # (정상적인 날짜로 인식했을 떄의 결과) 2023. 12. 24. (일) 00:00:00 KST
    else    
        CHK_DATE=$(date -d $DATE 2> /dev/null)    

        # 표준에러를 /dev/null 로 보내기 때문에
        # 인식할 수 없는 날짜인 경우 결과가 비게 됨. 
        if [ -z $CHK_DATE ]; then    
            echo '날짜를 인식할 수 없습니다. 다시 입력하세요.'    
        else    
            # 날짜 정합성 검사를 통과하면 새로 입력받을 필요가 없으므로    
            # break 으로 while loop 을 빠져나온다.    
            break;    
        fi    
    fi       
done

 

파일명 정합성 검사하기

이번에는 프로그램 실행결과를 저장할 파일명을 지정하는 경우이다.

기존재하는 파일명인 경우에 덮어쓰도록 할 경우라면 리다이렉션 연산자를 '>>' 으로 쓰면 되기 때문에 크게 고려할 필요가 없다.

 

동일한 파일 존재 시에 덮어쓸지 물어서 Y 로 답한 경우에만 처리해야 한다면?

역시나 while 을 써서 처리할 수 있다. 로직은 다음과 같다.

 

while [ true ]
do
    # 입력값을 SAVE_FLNM 변수에 저장한다
    read -p '생성할 파일명을 입력하세요: ' SAVE_FLNM
    
    # 기존재하는 파일인지 검사한다.
    # BASH 에서는 전체경로를 넣어도 상관없다.
    # 어차피 '-f' 연산자가 입력값이 파일인지 검사하기 때문이다.
    if [ -f $SAVE_FLNM ]; then
    
        # 입력값을 OVR_YN 변수에 저장한다.
        read -p '이미 존재하는 파일입니다. 덮어쓸까요? [Y/N] ' OVR_YN
        
        # ${변수명,,} 으로 알파벳을 소문자로 변환한다.
        # 소문자로 변환하면 Y, y, N, n 에 대해 모두 검사할 필요가 없다.
        if [ "${OVR_YN,,}" == "y" ]; then
            break;
        fi
        
    # 유닉스/리눅스에서는 디렉토리도 파일로 인식되기 때문에
    # DOS/Windows CMD 쉘과 달리, 같은 이름으로 공존할 수 없다.
    elif [ -d $SAVE_FLNM ]; then
        echo '동일한 이름을 지닌 디렉토리가 존재합니다'
    else
        break;
    fi
done

 

전후 날짜 구하기

날짜를 입력으로 받아서 1일전, 한달 후 등 전후를 구해야 할 때가 있다.

다행히 date 유틸에서 이 기능을 지원한다.

 

위에서 date -d '날짜' 로 이 입력값이 인식가능한 날짜인지 검사하는 기능이 있었는데 여기에 +, - 를 이용해서 날짜를 더하거나 뺄 수 있다.

# 특별히 포맷을 지정하지 않을 경우
$ date
2023. 12. 24. (일) 01:02:22 KST


# yyyymmdd 으로 출력하고 싶을 때
$ date '+%Y%m%d'
20231224

# 날짜를 입력으로 받아서 특정 포맷으로 출력할 경우
$ date '+%Y%m%d' -d '20231223'
20231223

# 하루 뒤를 구할 경우, 날짜 뒤에 '+1 day' 를 추가
$ date '+%Y%m%d' -d '20231224 +1 day'
20231225

---

# 1년 후
$ date -d '20231224 +1 year'
2024. 12. 24. (화) 00:00:00 KST

# 20개월 전을 구할 때
$ date -d '-20 year'
2003. 12. 24. (수) 01:11:13 KST