[Linux 셸 스크립트] bash - 126 사칙 연산을 간단하게 작성하기
본문 바로가기
IT 이야기/Linux 셸 스크립트

[Linux 셸 스크립트] bash - 126 사칙 연산을 간단하게 작성하기

by 찬찬이 아빠 2021. 7. 6.
반응형
  1. 사용 명령어

(1) echo

 

  2. 키워드 & 사용처

(1) 키워드

산술식, 산술 확장, 산술 평가

 

(2) 사용처

expr 명령어를 사용하지 않고 산술식을 계산한 결과를 얻고 싶을 때 사용합니다.

 

  3. 실행 예제
$ ./bash-arithmetic.sh
	1.txt에서 100.txt 까지 100개의 파일이 작성됨

 

 

  4. 스크립트

#!/bin/bash

 

# 브레이스 확장으로 1에서 100까지 숫자 목록 생성

for i in {1..100}                     

do

    # 산술 확장을 이용해서 파일명에 3을 곱해서 계산한

    # 값을 텍스트 파일에 저장

    echo $((i * 3)) > ${1}.txt             

done

 

 

  5. 해설

이 스크립트는 1에서 100가지의 파일명을 가진 파일을 작성합니다. 파일 내용은 파일명 숫자에 3을 곱한 값입니다. 어떤 테스트 파일을 대량으로 만들고 싶을 때 사용하면 유용합니다.

 

우선 에서 브레이스 확장을 이용해서 1에서 100까지 숫자 목록을 만듭니다.

에서 bash 고유 기능인 산술 확장(Arithmetic Expansion)을 이용합니다. 이 방법은 $((산술식))이라고 하는데, 괄호 안 산술식을 계산해서 그 결과를 숫자로 확장하는 표기법입니다. 이 산술식은 변수명 앞에 있는 $ 기호를 생략할 수 있습니다. 산술 확장은 일반적으로 sh 셸 스크립트에서 expr 명령어로 계산한 부분을 치환하는 목적으로 이용됩니다.

 

산술 확장에서 자주 사용하는 연산자는 다음과 같습니다. 자바나 C 언어에서 이용하는 연산자와 거의 같으므로 어렵지 않을 것입니다.

연산자 설명
+ 덧셈
- 뺄셈
* 곱셈
/ 나눗셈(버림)
% 나머지
** 제곱
<< 왼쪽 쉬프트(비트 연산)
>> 오른쪽 쉬프트(비트 연산)

산술 확장은 expr 명령어와는 달리 외부 명령어를 이용하지 않고 게산하여 속도가 무척 빠릅니다. 또한 변수명에 $가 필요 없으므로 곱셈 연산자 *를 이스케이프하지 않아도 되어 작성하기 편리합니다.

result=$(expr $i \* $i)       <- expr 명령어는 곱셈 기호에 이스케이프 필요
result=$((i * i))       <- 산술 확장은 $과 이스케이프 불필요

그리고 산술 확장과 비슷한 예로 산술 평가(Arithmetic Evaluation)가 있습니다. 이것은 산술식을 평가해서 그 참과 거짓을 돌려줍니다. 따라서 if문이나 while문 조건식으로 test 명령어 대신에 사용하는 경우가 많습니다. 또한 증감/차감 연산자는 대입 연산 없이 단독으로도 사용할 수 있습니다. 연산 결과를 돌려주지 않아서 산술 확장보다는 산술 평가로 이용하는 것이 일반적입니다.

 

다음은 산술 평가를 이용해서 while 반복문을 작성하는 예입니다. expr 명령어를 사용하지 않으니 셸 스크립트 특유의 번잡함이 줄어드는 걸 알 수 있습니다.

#!/bin/bash

# i=1에서 9까지 while 반복 처리
i=1
while ((i < 10))
do
	처리 내용
    ((i++))
done

이렇듯 bash 산술 확장, 산술 평가를 이용하면 다양한 수치 계산을 간단히 작성할 수 있습니다. 또한 expr 명령어 오버헤드도 없어져서 스크립트가 빨라지는 것도 기대할 수 있습니다.

 

 

<주의사항>

산술 확장은 변수 앞 $ 기호를 생략할 수 있는데 예외적으로 인수를 나타내는 위치 파라미터($1, $2 등)만 $ 기호를 생략하면 예를 들어 $1은 1이 되어서 숫자와 구분이 가지 않기 때문입니다.

산술 평가에는 let 명령어를 이용하는 방법이 있습니다. 다음처럼 let 명령어 인수에 산술을 넘기면 산술 평가 표기법(())과 마찬가지로 산술식이 실행되어서 참/거짓 값이 돌아옵니다. 다음 두 줄은 같은 의미입니다.

((i++))
let 'i++'

셸 변수를 declare문 -i 옵션으로 정의하면 대상 변수는 $(()) 표기법을 사용하지 않아도 산술 확장을 이용할 수 있습니다.

 

 

 

참고서적 : 유닉스 리눅스 셸 스크립트 예제 사전

반응형

댓글