http://blog.daum.net/_blog/BlogTypeView.do?blogid=0K6Pu&articleno=6271130&_bloghome_menu=recenttext

 

1. substring  함수

 

 

 ${var:start:length}

    var : 변수명

    start : 변수 값인 문자열로부터 substring 기능을 수행할 시작 위치 인덱스 번호로써 0부터 시작

    length : 추출할 문자열 길이, length를 서술하지 않으면 start로 시작하는 나머지 전제 문자열을 추출한다.

 

위 함수(기능)는 POSIX 기준인 본쉘(sh)에서는 지원하지 않고 콘쉘 및 배쉬쉘에서 지원하는 기능이다. 보편적인 프로그래밍 언어(또는 인터프리터)에서 제공하는 함수인 substring의 기능을 수행하는 것으로써 문자열의 일부분을 추출한다. 원본 문자열(var의 값)은 변경하지 않는다.

 

예제)

 

1   $ var="abcdef"

2   $ a=${var:0}

3   $ echo $a

4   abcdef

5   $ a=${var:0:3}

6   $ echo $a

7   abc

8   $ a=${var:3:0}

9   $ echo $a

10

11 $ a=${var:3:1}

12 d

 

 

 

2. cut 시스템 호출

 

 

 -c 옵션    단순 substring 함수와 동일한 기능으로 인덱스가 0부터 시작하지 않고 1부터 시작하는 것이 다르다.
 -f 옵션    필드 구분자(delimitr)를 지정하여 문자열 중 특정 필드를 추출한다.

 

cut은 /usr/bin 등의 디렉토리에 존재하는 실행프로그램으로써 보편적으로 주어진 입력(파일 또는 표준입력)에서 특정 필드 또는 컬럼을 추출하는 프로그램이다. 이러한 시스템 호출을 통한 문자열 조작은 cut 뿐만 아니라 sed, awk를 이용하여 수행될 수 있다. 위에 열거한 -c, -f 옵션 외에도 다양한 기능을 갖고 있으나 여기서는 -c, -f 옵션에 대하여 간단한 예를 들어 설명한다.

 

예제) cut -c

 

1  $ echo abc defghi | cut -c1

2  a

3  $ echo abc defghi | cut -c1-5

4  abc d

5  $echo abc defghi | cut -c2-5

6  bc d

 

${var:start:length}와 다르게 -c의 뒤에 붙는 시작 위치 인덱스 번호가 0-base 인덱스가 아닌 1-base 인덱스이고 또한 두 번째 인덱스 번호는 추출할 문자열 길이가 아닌 컬럼 인덱스 번호가 된다. 즉, ${var:start:length}는 from-length이고 cut -c는 from-to이다.

 

예제) cut -f

 

1  $ echo abc defghi | cut -f1

2  abc defghi

3  $ echo abc defghi | cut -f1 -d" "

4  abc

5  $ echo abc defghi | cut -f2 -d" "

6  defghi

7  $ echo abc defghi | cut -f2

8  abc defghi

 

특정 필드를 추출하며 -d 옵션으로 필드 구분자를 지정한다. 따로 필드 구분자를 지정하지 않으면 탭 문자를 기본 필드 구분자로 처리한다. 7번 라인에서 필드 구분자가 탭 문자이므로 -f2에 해당하는 두 번째 필드가 공백이어야 할 것 같으나 문자열에서 필드 구분자를 만나지 못하면 필드 추출을 하지 않고 입력된 문자열을 출력한다. 때문에 2번 라인에서 출력된 값 역시 1번 필드를 나타내는 것이 아니고 입력된 문자열에서 필드 구분자를 만나지 못했으므로 입력 값을 그대로 출력한 결과가 되는 것이며, 정상적으로 필드를 찾아서 출력한 것은 3번과 5번 명령 뿐이다.

 

cut은 실행프로그램 호출이므로 유닉스 명령어 cut을 참고하면 자세히 알 수 있을 것이다.

 

 

 

 

 

3. null 비교 문자열 조작 기능

 

 

 ${#var}     변수 var가 가지는 문자열의 길이를 구한다.
 ${var:-word}

     1. 변수 var의 값이 null이 아니면 : var의 값을 반환, var의 값은 변하지 않는다.

     2. 변수 var의 값이 null이면         : word의 값을 반환, var의 값은 변하지 않는다.

 ${var:=word}

     1. 변수 var의 값이 null이 아니면 : var의 값을 반환, var의 값은 변하지 않는다.

     2. 변수 var의 값이 null이면        : word의 값을 반환, var의 값은 word의 값으로 대체된다.

 ${var:+word}

     1. 변수 var의 값이 null이 아니면 : word의 값을 반환, var의 값은 변하지 않는다.

     2. 변수 var의 값이 null이면        : null을 반환, var의 값은 변하지 않는다.

 ${var:?word}

     1. 변수 var의 값이 null이 아니면 : var의 값을 반환, var의 값은 변하지 않는다.

     2. 변수 var의 값이 null이면        : null이면 에러 메시지인 word를 출력하고, 쉘 스크립트를 종료한다.

 

     2번 째 경우이고 word가 생략되었다면 "parameter null or not set" 라는 메시지를 출력하고 쉘 스크립트를

     종료한다.

 

위의 표에서 ${var:+word}의 경우에만 변수 var의 값이 null이 아니면 word의 값을 반환하고, 나머지 경우에는 모드 var를 반환하는 것으로 다른 작업과는 반대의 성향을 보인다.. 그리고 var의 값이 변하는 경우는 ${var:=word}의 작업에서 var값이 null인 경우에만 var의 값이 word로 대체된다.

 

 

 

 

 

4. 일치되는 패턴 제거 후 나머지 문자열 반환

 

 

 ${var%pattern}    끝에서 부터 word와 패턴이 일치하는 var의 최소 부분(첫번째 일치)을 제거하고 나머지를 반환한다.
 ${var%%pattern}    끝에서 부터 word와 패턴이 일치하는 var의 최대 부분(마지막 일치)을 제거하고 나머지를 반환한다.
 ${var#pattern}    처음 부터 word와 패턴이 일치하는 var의 최소 부분(첫 번째 일치)을 제거하고 나머지 부분을 반환한다.
 ${var##pattern}    처음 부터 word와 패턴이 일치하는 var의 최대 부분(마지막 일치)을 제거하고 나머지 부분을 반환한다.

 

위의 설명에서 pattern은 정규식이 아니라 *와 ?의 와일드 카드 패턴이다. %% 또는 ## 의 경우 pattern이 일치하지 않을 때 까지 반복해서 var의 값을 검색하지만 % 와 # 는 처음 일치하는 패턴이 나올 때 까지만 찾는다. 실제로 리눅스(우분투)의 bash에서 테스트를 해본 결과 와일드 카드 *에 대해서는 정상적으로 수행되었으나 또 다른 와일드 카드인 ?에 대해서는 %%와 ##에 의한 반복적인 패턴 매칭이 수행되지 않았다.

 

예제) ${var%pattern}

 

1  $ var="usr/X11R6/bin/startx"

2  $ result=${var%/*}

3  $ echo $var

4  usr/X11R6/bin/startx

5  $ echo $result

6  usr/X11R6/bin

 

이 예제에서 2번째 라인의 와일드카드 패턴인 /* 의 의미가 슬래쉬(/)로 시작하면서 0개 이상 문자열이 뒤따르는 것을 의미하므로 "/startx" 부분이 제거된 값인 "/usr/X11R6/bin"이 변수 result에 치환되었다. 변수 var의 값은 변하지 않았다.

 

예제) ${var%%pattern}

 

1  $ var="usr/X11R6/bin/startx"

2  $ result=${var%%/*}

3  $ echo $var

4  usr/X11R6/bin/startx

5  $ echo $result

6  usr

 

여기서는 2번째 라인에 연산자를 %%로 사용했으므로 뒤에서부터 반복적으로 매칭되는 패턴을 찾아간다. 패턴이 일치하는 "/startx" 가 제거되고 반복적으로 "/bin" 과 "/X11R6" 역시 "/*"의 와일드 카드 패턴에 일치하므로 제거되었고 "usr"은 슬래쉬(/)로 시작하지 않으므로 패턴이 매치되지 않았기 때문에 "/X11R6/bin/startx" 부분이 제거된 값인 "usr"이 변수 result에 치환되었다. 마찬가지로 변수 var의 값은 변하지 않았다.

 

예제) ${var#pattern}

 

1  $ var="usr/X11R6/bin/startx"

2  $ result=${var#/*}

3  $ echo $var

4  usr/X11R6/bin/startx

5  $ echo $result

6  usr/X11R6/bin/startx

 

이 예제는 앞에서 부터 패턴을 찾는데 변수 var의 값이 슬래쉬(/)로 시작하지 않으므로 매치되는 패턴을 찾지 못하므로 변수 var의 값에서 제거되는 부분이 없이 "usr/X11R6/bin/startx"의 값이 그대로 result에 치환된다. 2번째 라인에 연산자를 ##로 사용하여도 처음부터 패턴을 찾지 못하므로 같은 결과가 나온다.

 

예제) ${var##pattern}

 

1  $ var="/usr/X11R6/bin/startx"

2  $ result=${var##/*}

3  $ echo $var

4  /usr/X11R6/bin/startx

5  $ echo $result

6  

 

이번에는 변수 var값의 앞에 슬래쉬(/)를 붙여 보았다. 결과적으로 와일드카드 패턴인 "/*"에 매치되는 "/usr"이 제거되고 반복적으로 "/X11R6", "/bin"과 "/startx"가 제거되어 변수 result에는 null 값이 치환된다. 2번째 라인에서 ##가 아닌 #를 썼다면 result의 값은 "/X11R6/bin/startx"이 된다.

 

예제) 와일드카드 ?를 사용한 경우

 

1  $ var="/aa/aa/aaa/aa/aa"

2  $ result=${var##/??}

3  $ echo $var

4  /aa/aa/aaa/aa/aa

5  $ echo $result

6  /aa/aaa/aa/aa

 

위의 경우에 ## 연산자를 사용했으므로 슬래쉬(/)로 시작하고 두개의 문자가 뒤따르는 문자열을 반복적으로 제거해야 하므로 "/aa/aa/aa"가 제거된 "a/aa/aa"가 결과 값으로 반환되어야 하지만 실제로는 처음 한번 매치되는 패턴인 "/aa"만 제거되었다. 때문에 패턴비교 문자열 조작 기능을 사용할 때는 가급적 와일드카드 ?는 사용하지 않거나 주의를 하여 사용하는 것이 좋을 듯하다.

'리눅스' 카테고리의 다른 글

pam_tally2 확인 및 초기화  (0) 2016.03.30
awk 필드 변수, 빌트인 변수  (0) 2016.03.28
리눅스 네임서빙 우선순위 결정 : /etc/host.conf  (0) 2016.03.03
tcpwrapper iptable 차이  (0) 2015.10.05
htaccess 설정방법  (0) 2015.09.22
Posted by 캐논볼
,