쉘 스크립트에서의 사칙연산과 문자열 자르기

Posted by taeho Tae-Ho
2013.10.08 10:00 운영체제

쉘에서 문자열 자르기를 설명하기 전에 쉘에서의 변수의 특징을 먼저 알아 보자.


일반적인 Java나 C와 같은 프로그래밍 언어에서는 변수의 선언과 타입(type)이 무척 중요하다. 선언하지 않고 사용하거나 잘못 참조하거나 잘못 연산하게 되면 엉뚱한 값이 출력되거나 컴파일 시 에러를 팍팍~뿌려댄다. 하지만 쉘스크립트에서는 변수는 선언하지 않으며 타입을 지정하지 않고 사용해도 된다. 


이따금씩 쉘 스크립트를 짜다보면 문자열과 숫자의 취급이 헷갈리곤 한다. C언어나  Java언어에서는 변수에 저장될 값이 숫자냐 문자냐를 무척 따져 형변환을 안해주게 되면 가차없이 컴파일 시 에러를 뿌려주는데 반해 쉘 스스크립트는 거침없이 알아서 연산을 한다.


아래 두 스크립트를 비교해보자.


a=10

b=10


let c=a+b


echo $a+$b=$c                                                                                  --> 출력결과 :  10+10=20


c=$a$b


echo $c                                                                                            --> 출력결과 : 1010


변수 a,b에 10이라는 숫자가 저장된 것으로 생각하겠지만 변수 a와 b는 숫자형으로도 사용이 가능하고 문자열로도 사용이 가능하다. 즉 산술연산식에 변수를 사용하면 숫자로 인식되어 계산되고 문자열 연산에 사용되면 문자열로 인식되어 합쳐지게 된다. 또한 연산의 결과를 받는 변수 c도 연산의 결과에 따라 숫자로 사용되기도 하고 문자로 사용되기도 한다.


아래의 스크립트도 앞의 스크립트와 같은 결과를 보여준다.


a="10"

b="10"


let c=a+b


echo $a+$b=$c                                                                          --> 출력결과 : 10+10=20


c=$a$b


echo $c                                                                                    --> 출력결과 : 1010


변수 a와 b의 초기화에 큰따옴표(")가 사용되어 언뜻 문자열로 사용될 것 같지만 연산식에 따라 숫자로도, 문자열로도 그때 그때 알아서(?) 쉘이 연산을 해준다.


쉘에서 변수의 특징을 이해하였다면 문자열 자르기로 넘어가자.


많은 스크립트 언어와 컴파일 언어에서는 문자열을 합치고 자르는 다양한 이해하기 쉬운 함수를 제공한다. 하지만 쉘에서는 조금 어렵다. 아니 어렵다기보다는 설명이 없이는 난해하다.


자릿수에 의한 문자열 자르기


${var:start:length} 

var : 문자열이 포함된 변수

start : 변수로부터 잘라낼 문자의 시작 번호 (0부터 시작됨)

length : start부터의 잘라낼 문자 갯수. length가 기술되지 않으면 끝까지.


예제 : 

IP="192.168.100.10"


echo "IP : "$IP


echo "12 to 2 : "${IP:12:2}


예제는 위의 하나로 충분하다고 본다.

IP라는 변수에 저장된 문자열 중에서 13번째 부터 2개의 문자열을 잘라내겠다는 의미다. 13번째인데 12가 쓰인 이유는 잘라내기 시작할 start는 0에서 부터 시작하기 때문이다. 일반적인 상식에서는 1이 숫자의 시작으로 생각하겠지만 프로그래밍에서 숫자의 시작은 0인 경우가 많다. 


패턴(구분자) 의한 문자열 자르기


 ${var%pattern}

문자열 변수 var의 끝에서 부터 pattern을 찾아 첫번째로 나타나는 패턴 문자열을 버린다.

 ${var%%pattern}

문자열 변수 var의 끝에서 부터 pattern을 찾아 마지막으로 나타나는 패턴 문자열을 버린다.

 ${var#pattern}

문자열 변수 var의 앞에서부터 pattern을 찾아 첫번째로 나타나는 패턴 문자열을 버린다.

 ${var##pattern}

문자열 변수 var의 앞에서부터 pattern을 찾아 마지막으로 나타나는 패턴 문자열을 버린다. 


음...이해가 쉽게 된다면 당신에게 경의를 표한다. -.- 내 머리는 나빠서인지 왜 이렇게 난해한 기호들을 나열하여 만들었는지 쉘이나 펄을 만든 이들에게 경외심마저 생긴다. 


${     } 는 중괄호{ } 안의 문자열을 처리를 수행하는 연산식이라는 것을 의미한다. 

var는 문자열이 저장된 변수다.

%와 #는 변수(var)에서 pattern을 찾기 시작하는 위치다. %는 문자열의 끝에서부터 pattern을 찾기 시작하며 #은 문자열의 처음부터 pattern을 찾기 시작한다.

pattern 은 잘라낼 패턴이다. 


가장 중요한 것은 pattern인데..... 여기가 좀 헷갈릴 수 있다. 예제를 보자.

[taeho@ncsd shell]$ cat str.sh

IP="192.168.100.10"

echo "IP : "$IP

echo ${IP%.*}


[taeho@ncsd shell]$ ./str.sh

IP : 192.168.100.10

192.168.100


가장 뒷부분을 잘라내서 버린다는 의미에서 패턴에 %를 사용했다.

다음과 같이 문자열을 자를 때 패턴으로 사용될 구분자.(마침표) 로 지정했다. 

와일드카드로 *을 사용했다. 즉 . 으로 시작하는 문자열 패턴이라는 의미에서 .* 인 것이다.

${IP%.*}


 192.168.100.10 에서 .으로 시작하는 문자열 패턴을 찾아 가장 마지막 패턴을 포함하는 문자들을 잘라내 버리는 것이다.


%를 두번쓰면 즉 %%를 사용하면 반대로 처음으로 .* 패턴이 나타나는 부분부터 끝까지를 버린다.

[taeho@ncsd shell]$ cat str.sh

IP="192.168.100.10"

echo "IP : "$IP

echo ${IP%%.*}

[taeho@ncsd shell]$ ./str.sh

IP : 192.168.100.10

192

[taeho@ncsd shell]$ 


pattern에서 %와 #의 차이는 패턴을 찾기 시작하는 문자열의 위치라고 앞에서 이야기했다.

일반적인 문자열이라면 %와%% #과 ##을 써서 동일한 결과를 뽑아낼 수 있지만 특이한 문자열 (예를 들면 맨 앞에 구분자로 사용할 특수문자(/,.| 등)가 있는 경우도 있고 없는 경우도 있을 경우...) 의 경우에는 구별하여 사용해야 한다.


정확한 의미를 이해하려면 여러가지 경우로 테스트해보기 바란다.


이전 포스트 보기 : [unix / linux] shell (쉘)을 이해하자.


신고
이 댓글을 비밀 댓글로