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

비교 연산자

by 멸치김밥 2021. 12. 21.
  • 정수 비교

 

쉘 스크립트에서는 관계연산자를 등호, 부등호가 아닌 알파벳으로 사용한다.

해당 관계 연산자의 조건에 충족하면 참, 그렇지 않으면 거짓을 반환한다.

if와 같은 곳에 쓰이며 종류와 사용예시는 다음과 같다

  • -eq : equal / 두 피연산자가 같은 경우
  • -ne : not equal / 두 피연산자가 다른 경우
  • -lt : less than / 왼쪽 피연산자가 오른쪽 피연산자보다 작은 경우
  • -le : less equal / 왼쪽 피연산자가 오른쪽 피연산자보다 작거나 같은 경우
  • -gt : great than / 왼쪽 피연산자가 오른쪽 피연산자보다 큰 경우
  • -ge : great equal / 왼쪽 피연산자가 오른쪽 피연산자보다 크거나 같은 경우
if [ 3 -le 5 ] 
then
	echo "참입니다"
fi

a=20
b=10
if [ $a -gt $b ]
then
    echo "참치입니다"
fi

  • 문자열 비교

두 피연산자가 문자열일 경우 사용할 수 있다.

일부는 대괄호를 두번 감싸는 형식으로 사용해야 한다. --> [[ 피연산자A > 피연산자B ]] 

  • = : 두 피연산자가 같은 경우
  • == : = 와 동일하다

찾아보아도 둘다 똑같은 기능이라 설명되어있다..

#!/bin/bash
a=20
b="20"
if [ $a = $b ]; then
    echo "a는 b랑 같음"
fi
if [ $a == $b ]; then
    echo "a는 b랑 같음"
fi
a는 b랑 같음
a는 b랑 같음

20과 "20" 을 비교해도 문자열로 여기고 비교하는 녀석이라 그런건지 결과에 변화는 없다.

 

 

  • != : 두 피연산자가 같지 않은 경우
#!/bin/bash
a=10
b=20
if [ $a != $b ]; then
    echo "a는 b랑 다름"
fi
a는 b랑 다름

 

 

  • =~ : 뒤 피연산자 문자열이 앞 피연산자 문자열에 포함되는 경우
#!/bin/bash
a=123456
b=34
c=43
if [[ $a =~ $b ]]; then
    echo "a문자열 안에 b문자열이 포함되어있음"
fi
if [[ $a =~ $c ]]; then
    echo "a문자열 안에 c문자열이 포함되어있음"
fi
if [[ $a = *$b* ]]; then
    echo "a문자열 안에 b문자열이 포함되어있음"
fi
if [[ $a = 1*5*6 ]]; then
    echo "a문자열 안에 시작문자는 1이고 중간에 5문자도 있고 6으로 끝남"
fi
a문자열 안에 b문자열이 포함되어있음
a문자열 안에 b문자열이 포함되어있음
a문자열 안에 시작문자는 1이고 중간에 5문자도 있고 6으로 끝남

'123456' 안에 '34'가 있으므로 ture이고 c의 경우는 문자들이 a에 들어있긴 하지만 똑같이 나열된 문자열이 아니기에

false가 반환되었다.

*을 문자열 앞뒤에 붙이면 =~과 동일한 기능을 한다.

*은 문자열 앞, 뒤, 사이에 넣을 수 있으며 *이 있는 공간엔 어떤 문자열이 존재해도 되고 안해도 된다.

 

 

  • > : 사전 순에 따라 앞 피연산자가 뒤 피연산자보다 큰 경우
  • < : 사전 순에 따라 앞 피연산자가 뒤 피연산자보다 작은 경우
#!/bin/bash
a=123456
b=34
if [[ $a > $b ]]; then
    echo "a문자열이 b문자열보다 사전순서 상 앞에 있음(a가 b보다 순서가 큼)"
fi
if [[ $a < $b ]]; then
    echo "a문자열이 b문자열보다 사전순서 상 앞에 있음(a가 b보다 순서가 작음)"
fi
a문자열이 b문자열보다 사전순서 상 앞에 있음(a가 b보다 순서가 작음)

문자들의 정렬을 생각해보면 오름차순이 A~Z, 0~9 순서이므로 A보다 Z가 크고, 0보다 9가 크다는것을 생각하고 연산자를 보면 되겠다.

값이 아닌 순서의 크기(?) 를 비교하는 것이기 때문에 앞의 문자가 동일하지 않는 이상 뒤 문자열들의 크기는 중요하지않다.

 

 

  • -z : (zero) 뒤의 오는 피연산자의 문자열 길이가 0인 경우
  • -n : -z와 반대의미로 문자열의 길이가 0이 아닌 경우
#!/bin/bash
a=''
b=' '
c=
if [[ -z $a ]]; then
    echo "a의 문자열 길이는 0이다"
fi
if [[ -z $b ]]; then
    echo "b의 문자열 길이는 1(공백한칸) 이므로 이건 출력안됨"
fi
if [[ -z $c ]]; then
    echo "c의 문자열 길이는 0이다"
fi
unset b
if [[ -z $b ]]; then
    echo "unset 한 변수는 c와 같은 상태가 되고, 고로 길이가 0이 되어 출력된다"
fi
a의 문자열 길이는 0이다
c의 문자열 길이는 0이다
unset 한 변수는 c와 같은 상태가 되고, 고로 길이가 0이 되어 출력된다

a는 문자열 '' 안에 아무것도 없으니 true를,

b는 길이가 1이므로 false,

c는 변수 안에 아무것도 없는 상태라서 true가 나왔다.

그 다음 b를 unset하고 다시 대입해보았더니 true가 나왔다.

-n 의 경우는 그냥 위와 반대되는 경우라 생략한다.


  • 복합 비교
  • ! : 논리 부정, 어떤 조건의 앞에 ! 를 붙여주면 참, 거짓을 반대로 반환한다.
  • -o : or / 두 피연산자 중 하나라도 참인 경우
  • -a : and / 두 피연산자 모두 참인 경우
  • || : or / 두 피연산자 중 하나라도 참인 경우
  • && : and / 두 피연산자 모두 참인 경우
#!/bin/bash
a=0
b=1
c=2
if [ $a -lt $b -o $b = $c ]; then
    echo "참"
fi
if [ $a -lt $b ] || [ $b = $c ]; then
    echo "참"
fi
if [[ $a -lt $b && $b -le $c ]]; then
    echo "참"
fi
참
참
참

-o 와 || , -a 와 && 는 똑같은 OR연산자와 AND연산자인데

쉘 스크립트의 특성상(?) -o, -a 는 [ ] 안에서만, 반대로 ||, && 는 [ ] 밖이나 [[ ]] 안에서만 사용할 수 있다.

 


  • 파일 테스트 연산자

해당하는 조건에 충족하면 참을 반환한다

  • -b [파일명] : 파일이 존재하고 블록 디바이스 파일인 경우
  • -c [파일명] : 파일이 존재하고 문자 디바이스 파일인 경우
  • -d [파일명] : 파일이 존재하고 디렉토리인 경우
  • -e [파일명] : 파일이 존재하는 경우
  • -f [파일명] : 파일이 정규 파일인 경우
  • -g [파일명] : 파일이 존재하고 SetGID 비트가 설정된 경우
  • -G [파일명] : 파일의 그룹명과 실행하는 계정
  • -k [파일명] : 파일이 존재하고 Sticky 비트가 설정된 경우
  • -L [파일명] : 파일이 존재하고 심볼릭 링크인 경우
  • -O [파일명] : 파일의 소유자와 실행하는 계정이 일치하는 경우
  • -p [파일명] : 파일이 존재하고 파이프나 이름이 있는 파이프(FIFO 파일)인 경우
  • -r [파일명] : 파일이 존재하고 읽을 수 있는 경우
  • -s [파일명] : 파일이 존재하고 빈 파일이 아닌 경우
  • -S [파일명] : 파일이 존재하고 소켓인 경우
  • -t [파일명] : 파일 설명자가 있고 터미널과 연결되어 있는 경우
  • -u [파일명] : 파일이 존재하고 SetUID 비트가 설정된 경우
  • -w [파일명] : 파일이 존재하고 쓰기 가능한 경우
  • -x [파일명] : 파일이 존재하고 실행할 수 있는 경우
  • [파일A] -nt [파일B] : 파일A가 파일B보다 더 나중에 생성된 경우
  • [파일A] -ot [파일B] : 파일A가 파일B보다 더 이전에 생성된 경우
  • [파일A] -df [파일B] : 파일A과 파일B가 같은 파일을 가리키고 있는 경우

파일 테스트 연산자들은 파일을 불러와야 하기 때문에 

#!/bin/bash
kim_file=/home/leessangmin/workspace/file_test.sh
if [ -e $kim_file ]; then
    echo "안녕"
fi

if [ -e ./file_test.sh ]; then
    echo "안녕"
fi

if [ -e ../workspace ]; then
    echo "안녕"
fi
안녕
안녕
안녕

이처럼 조건문 안에 경로까지 다 적어주거나 변수에 경로를 담아 사용하는 식으로 쓸 수 있다.

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

쉘 스크립트로 오늘 날짜 정보가 입력된 파일 생성하기  (0) 2021.12.21
IF 와 CASE  (0) 2021.12.21
연월 입력받아 달력 출력하기  (0) 2021.12.21
배열  (0) 2021.12.20
리다이렉션  (0) 2021.12.19

댓글