앎을 경계하기

[가짜연구소3기] Data Engineer

[가짜연구소 3기] 데이터 엔지니어링 53 - Control Statements in Bash Scripting

양갱맨 2021. 10. 2. 15:53

bash에서 if문 사용하기

if [ 조건 ]; then
	#조건이 참일 때
else
	#조건이 거짓일 때
fi

주의할 점 : [] 사이에 조건을 작성할 때 반드시 처음과 마지막에 공백을 넣어야한다.

X="Queen"
if [ $x == "King" ]; then
	echo "$x is a King!"
else
	echo "$x is not a King!"
fi
Queen is not a King!

비교연산자를 사용한 조건문

X=10
if (($x > 5)); then
	echo "$x is more than 5!"
fi

비교연산자를 사용할 때는 대괄호 대신 더블 괄호를 사용해서 표현할 수 있다.

대괄호를 사용하지 못하는 건 아니다.

대괄호를 사용할 때는 비교연산자에 맞는 옵션을 대신 사용한다.

  • -eq : ==
  • -ne : !=
  • -lt : <
  • -le : <=
  • -gt : >
  • -ge : >=
x=10
if [ $x -gt 5 ]; then
	echo "$x is more than 5!"
fi
10 is more than 5!

기타 조건 플래그

  • -e : 파일이 존재하는지
  • -s : 파일이 존재하고 파일사이즈가 0보다 큰지
  • -r : 파일이 존재하고 읽을 수 있는지
  • -w : 파일이 존재하고 쓸 수 있는지

이 외의 조건 플래그들은 https://www.gnu.org/software/bash/manual//html_node/Bash-Conditional-Expressions.html 에서 확인할 수 있다.

복합 조건

조건이 여러 개인 경우 AND 또는 OR 연산자로 이어서 적용할 수 있다.

  • && : AND
  • || : OR

if 문과 커맨드 명령 조건

조건문의 조건을 커맨드 명령으로 넣는 것도 가능하다.

words.txt라는 파일이 있을 때, 'Hello World!' 라는 문자가 있는지 검사하는 bash script이다.

if grep -q Hello words.txt; then #-q 옵션을 사용해야 일치시 true를 반환한다.
	echo "Hello is inside!"
fi

shell-within-a-shell 형태로 조건넣기

if $(grep -q Hello words.txt); then #$() 커맨드 명령이 실행되고 그 결과를 if 조건으로 사용
	echo "Hello is inside!"
fi

Bash 에서 for 루프 사용하기

for x in 1 2 3
do
	echo $x
done
1
2
3

number range 사용하기

bash에서도 brace expansion이라고 하는 숫자 범위를 만들 수 있다.

{시작값..정지값..증가값} - 기본 증분값은 1이다.

for x in {1..5..2}
do
	echo $x
done
1
3
5

더블 괄호 사용하기

더블 괄호를 사용해서 숫자를 반복하는 방법도 있다.

for ((x=2;x<=4;x+=2))
do
	echo $x
done
2
4

glob 확장 사용하기

패턴 매칭을 사용해서 여러 개의 파일 반복을 할 수 있다.

for book in books/*
do
	echo $book
done
books/book1.txt
books/book2.txt

Shell-within-a-shell 사용하기

이터러블 객체를 shell-within-a-shell 형태로 사용하는 것도 가능하다.

for book in $(ls books/ | grep -i 'air') #air가 있는 데이터만 남김
do
	echo $book
done
AirprotBook.txt
FairMarketBook.txt

While 루프

while 루프는 for루프와 비슷한데 조건이 참이 아닐 때까지 계속 반복한다.

if문에서 사용했던 옵션 플래그를 사용할 수 있고, 다중 조건을 연결하는 연산자도 사용할 수 있다.

while은 다른 언어에서도 마찬가지이지만 조건이 거짓이 되어 반복이 종료되는 시점을 만드는 것이 중요하다. 무한루프에 빠질 수 있으니까!

x=1
while [ $x -le 3]; #$x<=3
do
	echo $x
	((x+=1)) #break condition trigger
done
1
2
3

만약 정지 조건이 없었다면 계속 1을 출력하는 무한루프에 빠지게 된다.


Case 문

앞서 본 if문과의 차이는 더 명확하고 효율적으로 조건문을 작성할 수 있다.

< 예시 >

  • sydney가 포함된 파일은 /sydney 폴더로 옮긴다.
  • melbourne 또는 brisbane이 포함된 파일은 삭제한다.
  • canberra가 포함된 파일은 파일이름을 원래 파일이름 앞에 IMPORTANT_ 단어를 추가한다.
  • 파일 이름은 ARGV로 받게된다.
if grep -q 'sydney $1; then
	mv $1 sydney/
fi

if grep -q 'melbourn|brisbane' $1; then
	rm $1
fi

if grep -q 'canberra' $1; then
	mv $1 "IMPORTANT_$1"
fi

복잡해보임

case문을 사용해보자

case문 기본 사용법

  • 변수 또는 문자열이 패턴 패칭될 값이다. shell-within-a-shell이 안에 들어가도 된다.
  • 패턴은 정규식을 사용한 패턴이다.
  • 각 패턴과 명령은 ) 로 구분한다.
  • 패턴)명령 조합은 ;;로 구분한다.
  • case문이 모두 만족하지 않을 때는 *) 패턴에 대한 default command를 작성하고 esac 를 써서 case문을 마무리한다.
case 변수 또는 문자열 in
	pattern1)
	command1;;
	pattern2)
	command2;;
	*)
	DEFAULT COMMAND;;
esac

기본 사용법을 배웠으니 아까의 if문 script를 case로 바꿔보자

case $(cat $1) in
	*sydney*)
	mv $1 sydney/ ;;
	*melbourne*|*brisbane*)
	rm $1 ;;
	*canberra*)
	mv $1 "IMPORTANT_$1" ;;
	*)
	echo "No cities found" ;;
esac