[Linux 셸 스크립트] bash - 128 변수 내부 문자열 일부를 치환하기
본문 바로가기
IT 이야기/Linux 셸 스크립트

[Linux 셸 스크립트] bash - 128 변수 내부 문자열 일부를 치환하기

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

(1) echo

 

  2. 키워드 & 사용처

(1) 키워드

파라미터 확장, 문자열, 치환, sed

 

(2) 사용처

변수 내부 문자열을 sed 명령어를 사용하지 않고 치환하고 싶을 때 사용합니다.

 

 

  3. 실행 예제
$ ./bash-where.sh perl
/opt/local/bin/perl
/usr/bin/perl

 

 

  4. 스크립트

#!/bin/bash

 

# 조사할 명령어 얻기

command="$1"         

 

# 인수 확인

if [ -z "$command" ]; then       

    echo "에러: 조사 대상 명령어를 지정하세요." >&2

    exit 1

fi

 

# 환경 변수 $PATH의 :을 스페이스로 치환, for문 반복해서 사용

for dir in ${PATH//:/ }         

do

    if [ -f "${dir}/${command}" ]; then

        echo "${dir}/${command}"

    fi

done        

 

 

  5. 해설

이 스크립트는 명령행 인수로 지정한 명령어가 환경 변수 경로에 있는지 탐색해서 존재하면 그 경로를 나열합니다. 실행 예에서 perl 명령어로 /opt/local/bin과 /usr/bin 두 곳에서 발견했다는 걸 알 수 있습니다.

 

예제에서는 tcsh라는 셸의 where 명령어를 모방한 스크립트를 작성합니다. tcsh는 bash와 다른 계열의 C 셸 일종으로 BSD계 유닉스에서 자주 사용했습니다. tcsh에는 어떤 명령어가 경로 어디에 존재하는지 모두 나열하는 where라는 명령어가 있습니다.

 

bash는 where 명령어가 없기 때문에 스크립트로 작성해보겠습니다. 예를 들어 펄이 시스템에 달느 경로로 복수 개 설치되어 있으면 그 상태를 확인하기 위해 사용하는 툴로 편리하겠지요.

 

에서 명령행 인수로 지정한 명령어를 위치 파라미터 $1에서 셸 변수 command에 대입합니다. 는 그 인수 내용을 확인해서 빈 문자열인지 test 명령어 -z 옵션으로 확인합니다. 빈 문자열이면 명령어가 지정되어 있지 않으므로 에러를 표시하고 exit 명령어로 종료합니다.

 

에서 bash 파라미터 확장 기능을 써서 :(콜론)을 스페이스로 치환합니다. 이런 문자열 치환은 일반적으로 sed 명령어를 사용하지만 bash에서는 표준 기능인 파라미터 확장으로 치환할 수 있어 외부 명령어인 sed를 사용하지 않아도 됩니다.

 

bash 파라미터 확장을 사용한 문자열 치환은 다음과 같은 서식을 이용합니다.

1. ${변수명/패턴/치환문자열}
[변수명]의 마지막 일치한 [패턴]만 [치환문자열]로 바꿉니다. sed 명령어의 's/패턴/치환문자열/'에 해당합니다.

2. ${변수명//패턴/치환문자열}
[변수명]의 일치한 모든 [패턴]을 [치환문자열]로 바꿉니다. sed 명령어의 's/패턴/치환문자열/g'에 해당합니다.

패턴 지정은 와일드 카드인 *(임의 문자열)와 ?(임의 한 문자), 문자 클래스 지정[...] 등을 사용할 수 있습니다.

 

에서 이용하는 변수 PATH는 명령어 경로 탐색을 지정하는 환경 변수로 다음처럼 콜론을 구분자로 지정합니다.

$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

콜론을 스페이스로 치환한 디렉터리 목록을 for문에 넘겨서 셸 변수 dir에 대입합니다. 각각의 경로에 명령행 인수로 지정한 명령어가 존재하는지 test 명령어 파일 확인 연산자 -f를 이용해서 확인하고 파일이 있으면 echo 명령어로 표시합니다.

 

이렇게 해서 명령어가 존재하는 모든 경로를 한 번에 표시할 수 있습니다. 같은 명령어가 여러 경로에 설치되어 있는지 확인하는 목적으로 사용할 수 있습니다.

 

 

<주의사항>

이 스크립튼느 for문에서 스페이스 구분자를 사용하므로 환경 변수 PATH에 스페이스를 포함한 디렉터리를 지정하면 제대로 동작하지 않습니다.

파라미터 확장을 사용할 수 없는 sh 스크립트는 변수 내부 문자열을 치환할 때 다음처럼 echo 명령어로 변수값을 출력해서 sed 명령어로 처리할 필요가 있습니다.

echo $PATH | sed 's/:/ /g'

문자열 치환 시 문자열 앞부분만 일치하는 /#이라는 표기법도 있습니다. 이것은 정규표현식에서는 ^로 표시하는 패턴입니다. 다음처럼 앞부분에 필요 없는 스페이스가 들어 있는 문자열과 없는 문자열이 있을 때 /#으로 치환하면 앞부분 스페이스가 있는 문자열은 치환되지 않습니다.

# 앞부분에 필요 없는 스페이스가 있음
str1=" http://www.example.com/"

# 스페이스가 없음
str2="http://www.example.com/"

echo ${str1/#http:/hxxp:}
echo ${str2/#http:/hxxp:}

다음처럼 첫 번째 셸 변수 str1은 앞부분에 스페이스가 있어서 일치하지 않는다는 걸 알 수 있습니다.

http://www.example.com/
hxxp://www.example.com/

그리고 이 외에는 반대로 끝 부분에서 일치하고 싶을 때는 /% 표기법을 사용합니다.

 

 

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

반응형

댓글