본문 바로가기

별걸다하는 IT/리눅스 유닉스

[리눅스 / 유닉스 / 셸 스크립트 ] 제어문 case 사용법, 예제, 정규식이 아니라 패턴 매칭!

[ 리눅스 Linux / 유닉스 Unix / 셸 프로그래밍 Shell Scripting 완전정복 목차 ]

안녕하세요~~ 오늘은 case문과 select문에 대해서 다뤄보려고 합니당

C언어든 자바든 프로그래밍을 한 번쯤 해보셨다면, 모를 수 없는 switch case문 기억하시나요~~~

셸 스크립트에도 일반 프로그래밍 언어와 같이 if, case문, 반복문 등등의 제어구조를 가지고 있습니다.

그 중 하나인 case문에 대해서 먼저 얘기를 해볼게요.

 

이전에 다뤘던 제어문 if 포스팅~

 

[리눅스 / 유닉스 / 셸 스크립트 ] IF문 조건문 - 셸 프로그래밍 기초

[ Linux / Unix / shell scripting 링크 모음 ] 안녕하세요~! 오늘은 프로그래밍하면 가장 먼저 배우는 조건문에 대해서 공부해볼게요 ㅎㅎ 처음에 Shell scripting에서 조건문을 배우면 쫌 헷갈려요. 왜냐면 C언..

jhnyang.tistory.com

 

case의 역할

case는 '경우의 수' 할때 '경우'라는 의미를 가지고 있죠~~

변수 var가 있는데 이 var가 1이나 2이냐 3이냐 경우에 따라서 다른 action을 취할 수 있게끔 해주는 역할을 합니다. 물론 if문으로도 구현할 수 있겠지만 경우의 수가 많다면 구문이 복잡해지기 때문에 case문이 보기에도 활용하기에도 더 편리해집니다. ㅎㅎ

 

셸에는 타입이 문자열밖에 없으므로~ case는 문자열과 일치하는 패턴을 찾아 해당하는 분기에 있는 명령어들을 실행시킵니당.

 

case문 문법

그럼 case문을 사용하기 전 어떻게 쓰는지 문법을 볼까요~

[[문법]]
case 문자열 in
  경우1) 명령어1;;
  경우2) 명령어2;;
  .. 
esac  

if 끝에 fi로 끝내듯이, case 끝에도 esac로 끝내야 합니다. ㅎㅎ esac는 단순히 case를 거꾸로 쓴거예요.

프로그래밍 언어에서 분기를 ':'로 했었다면 셸에서는 ')'로 하고 있습니당

문자열이 만약 경우2번과 일치한다면 ';;'나오기 직전까지 정의되어 있는 명령들을 수행합니다

case 문자열 in
 경우1) 
    명령 명령 명령
    ;;
 경우2)
    명령 명령 명령
    ;;
 * )
    명령 명령 명령
    ;;
esac

맨 밑에 보면 별표와 괄호가 있어요. 이건 만약 문자열이 경우1과 경우2 모두와 일치하지 않을 때, 나머지 * )로 가서 수행하게 됩니다.

C언어의 switch case문

프로그래밍 switch문의 마지막 'default:' 부문과 '* )' 역할이 같다고 할 수 있어요 ㅎㅎ

 

case문 실습예제

간단한 확인을 위한 실습입니당

var=$1   
#이렇게 하면 스크립트 파일을 실행시킬 때 첫번째 인자로 온 인수를 받아 var 변수에 저장합니다
case $var in
    one) echo this is one ;;
    two) echo this is two ;;
    three) echo this is three ;;
    *) echo this is default ;; #one, two, three가 아닐 때 이 분기를 탑니다
esac # 꼭 닫아주기

위처럼 test.sh를 작성한 후에 첫 번째 인자를 바꿔가면서 실행해보면~~

결과창

인자로 들어온 문자열과 일치하는 곳을 잘 찾아가 명령을 수행하는 것을 확인할 수 있습니다.

case 패턴 사용 예시

그 문자열이 꼭 완전 똑같아야 하는건 아니고 패턴만 일치해도 분기를 따릅니당.

test.sh 스크립트

read는 사용자로부터 입력을 받는 명령어입니다. read today는 즉 사용자로부터 입력을 받아서 today라는 변수에 저장하라는 의미~~

실습결과

제대로 달 부분만 매칭해서 출력되었죠?

패턴방식에서 ?는 하나의 문자를 매칭합니다. (정규식에서는 ?앞에 선행하는 문자가 있고 그 문자가 0개 또는 1개가 뒤따라오는걸 의미합니다)

 

또한 '또는'을 의미하는 '|'랑도 잘 사용됩니다.

case $date in 
  ??03?? | ??04?? | ??05??) echo 봄이구나~! ;; # 3월이거나 4월이거나 5월일 때
  ??06?? | ??07?? | ??08??) echo 여름이구나~! ;;
  ??09?? | ??10?? | ??11??) echo 가을이구나~! ;;
  ??12?? | ??01?? | ??02??) echo 겨울이구나~! ;;
  *) echo 얼씨구나~! ;;
esac

요렇게~~어떤 조건은 동일하게 처리하고 싶을때 묶어주면 됩니다.

 

이처럼 여러 갈래로 분기할 수 있는 특성 때문에 메뉴목록 등등 선택을 위한 부문에 자주 사용돼요ㅎㅎ

 

★ case문 사용할때 주의할점

주의해야할 게 case는 정규식을 사용하는게 아니예요 패턴을 사용합니다.

echo "001100" | grep -o '..11..'

사진 설명을 입력하세요.

이 코드의 결과가 001100인 것을 보면 정규식이 제대로 수행된 것을 알 수 있습니다

dot(.)가 정규식에서 하나의 문자와 대응하니까요!

그런데 밑의 case문에서 똑같은 정규식을 판별에 넣어줬는데, 001100이 '..11..'에 매칭되지 않았습니다. ㅎㅎ

case문은 정규식을 사용하지 않고 패턴방식을 사용하기 때문이예요 ㅎㅎ

 

패턴 사용예제

워낙 스크립트에서 정규식을 자주 사용하니까 모든 곳에서 정규식이 통할(?)거라 생각하는데

사실 bash자체는 정규표현식을 이해하지 못합니다. 스크립트에서는 grep, sed, awk와 같은 명령어나 유틸이리티가 정규 표현식을 해석해주는 거예요 ㅎㅎ

그래서 기본적인 제어명령어들 자체는 정규식이 아니라 파일확장(pathname expansion)에서 사용되는 와일드카드 방식의 패턴 매칭을 따릅니다. ㅎㅎ globbing이라고 해요.

같은 '?'나 '.' 기호도 파일면 확장에서 사용되면 정규표현식 때 사용했던 의미와는 다르게 해석될 수 있습니다. (같지 않으니까요~)

자세한건 패턴매칭과 정규식 차이점 포스팅을 참고하세요!

 

와일드카드를 이용한 간단한 몇가지 패턴매칭 방식에 대해서 예시를 들고 마무리할게요 ~ :)

case $str in
   a*     ) -> a로 시작하면 OK, 즉 a, aa, ab, aab 등등
   a?     ) -> a로 시작하는데 str문자열이 두 글자면 OK,
   a[bc]  ) -> ab 또는 ac 등 대괄호 안에 있는 글자 중 하나가 나오면 OK
   # +(패턴)은 패턴이 하나 또는 그 이상 나타날 수 있는 걸 의미
   test+(1|2).sh -> test1.sh test2.sh test11.sh test222.sh 등등 OK
   !(*.jpg|*.png) -> .jpg나 .png로 끝나지 않는 단어들 
esac

이 외에도 ?(), *(), @() 등등 많은 방식이 있습니당

 

오늘은 간단하게 case문의 문법과, 사용 방법, 주의할 점에 대해서 알아봤어요.

공감 or 댓글 or 광고보답은 질좋은 정보를 공유하는데 힘이됩니당 :)

다음에 뵈어요~~~~