bash 스크립트에서 패턴에 따라 문자열 추출


17

bash에서 문자열이 있다고 가정합니다 strname.

strname="ph7go04325r"

첫 번째 "3" 문자와 마지막 "r" 문자 사이의 문자를 추출 strname하여 결과를 문자열에 저장하고 싶습니다 strresult. 위의 예에서 결과 strresult는 다음과 같습니다.

strresult="25"

첫 번째 "3"문자가 반드시 문자열 위치 8에있는 것은 아닙니다strname . 마찬가지로 마지막 "r"은 반드시 문자열 위치 11에 있을 필요 는 없습니다 . 따라서 다음 두 문자열 모두 strname가 산출됩니다 strresult="25".

strname="ph11go04325raa"
strname="325r"
strname="rgo04325raa"

또한 strname=ph12go04330raa"항복해야합니다 strresult="30".

나는 bash 스크립팅을 처음 사용하고 있으며, 이와 같은 문자열 패턴 일치를 어디서 시작할지 모르겠다. 제안 사항 있어요?

답변:


28

bash (3.0 이상)에서 정규식을 사용하여 다음을 수행 할 수 있습니다.

if [[ $strname =~ 3(.+)r ]]; then
    strresult=${BASH_REMATCH[1]}
else
    echo "unable to parse string $strname"
fi

bash에서 정규식의 캡처 그룹은 특수 배열에 배치됩니다 BASH_REMATCH. 요소 0에는 전체 일치가 포함되고 1에는 첫 번째 캡처 그룹에 대한 일치가 포함됩니다.


10

표준 sh구문 (모든 버전 bash또는 다른 POSIX 호환 셸 과 함께 작동 )에서 다음을 수행합니다.

case $strname in
  (*3*r*) 
    strresult=${strname#*3}
    strresult=${strresult%r*};;
  (*)
    printf >&2 '%s\n' "Unable to parse string $strname"
esac

expr35 세의 Unices에서도 작동 하는 기존 솔루션 도 참조하십시오 .

expr "x$strname" : 'x[^3]*3\(.*\)r'

오래된 특질 와 함께 expr경기가 실패하면 0이 아닌 종료 상태 (미세)을 얻을 수 있다는 것입니다,하지만 당신은 (와 같이 반환 된 문자열가 해결되면 0으로 0이 아닌 종료 상태를 확인 strname=zz300rzz).


귀하의 문구 가 이전 버전의 bash 에서만 수행 할 수 있음을 잘못 암시한다고 생각합니다 . 물론 확장은 현대 쉘에서 여전히 훌륭한 접근 방법입니다.
kojiro 2019

1
@kojiro, 무슨 말인지 알 겠어. 초기 공식은 Jordan의 답변에 대한 후속 조치였습니다. 내 답변을 업데이트했습니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.