IT

정규식을 사용하여 bash에서 검색 및 바꾸기

lottoking 2020. 6. 25. 07:45
반응형

정규식을 사용하여 bash에서 검색 및 바꾸기


이 예제를 보았습니다.

hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}

이 구문은 다음과 같습니다. ${variable//pattern/replacement}

불행히도 pattern필드 (내가 사용하는 경우 전체 정규 표현식 구문을 지원하지 않는 것 .또는 \s예를 들어, 리터럴 문자를 일치 시키려고합니다).

정규식 구문을 사용하여 문자열을 검색 / 바꾸려면 어떻게해야합니까?


sed 사용 :

MYVAR=ho02123ware38384you443d34o3434ingtod38384day
echo "$MYVAR" | sed -e 's/[a-zA-Z]/X/g' -e 's/[0-9]/N/g'
# prints XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX

후속 항목 -e은 순서대로 처리됩니다. 또한 g표현식 플래그는 입력의 모든 항목과 일치합니다.

이 방법을 사용하여 좋아하는 도구를 선택할 수도 있습니다 (예 : perl, awk).

echo "$MYVAR" | perl -pe 's/[a-zA-Z]/X/g and s/[0-9]/N/g'

이렇게하면 더 창의적인 일치를 수행 할 수 있습니다 ... 예를 들어 위 코드에서 첫 번째 표현식에 일치가 없으면 (게으른 and평가 로 인해) 숫자 대체가 사용되지 않습니다 . 물론, 당신은 입찰을 수행하기 위해 Perl의 완전한 언어 지원을 가지고 있습니다 ...


이것은 실제로 bash에서 수행 할 수 있습니다.

hello=ho02123ware38384you443d34o3434ingtod38384day
re='(.*)[0-9]+(.*)'
while [[ $hello =~ $re ]]; do
  hello=${BASH_REMATCH[1]}${BASH_REMATCH[2]}
done
echo "$hello"

... 수율 ...

howareyoudoingtodday

이 예제는 bash에서 작동하며 sed를 사용할 필요가 없습니다.

#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
MYVAR=${MYVAR//[a-zA-Z]/X} 
echo ${MYVAR//[0-9]/N}

문자 클래스 괄호 표현식을 사용할 수도 있습니다

#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
MYVAR=${MYVAR//[[:alpha:]]/X} 
echo ${MYVAR//[[:digit:]]/N}

산출

XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX

그러나 @Lanaru가 질문을 올바르게 이해하면 "전체"또는 PCRE 확장 \s\S\w\W\d\D등이 PHP 루비 파이썬 등에서 지원 되는대로 작동하지 않는 이유가 있습니다 . 이러한 확장은 Perl 호환 정규 표현식 (PCRE) 및 쉘 기반 정규 표현식의 다른 형식과 호환되지 않을 수 있습니다.

이들은 작동하지 않습니다 :

#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//\d/}


#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo $hello | sed 's/\d//g'

모든 리터럴 "d"문자가 제거 된 출력

ho02123ware38384you44334o3434ingto38384ay

그러나 다음은 예상대로 작동합니다

#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo $hello | perl -pe 's/\d//g'

산출

howareyoudoingtodday

좀 더 명확히하기를 바랍니다.하지만 아직 혼란스럽지 않은 경우 REG_ENHANCED 플래그가 활성화 된 Mac OS X에서 이것을 시도하지 마십시오.

#!/bin/bash
MYVAR=ho02123ware38384you443d34o3434ingtod38384day;
echo $MYVAR | grep -o -E '\d'

대부분의 * nix 맛에서는 다음과 같은 결과 만 볼 수 있습니다.

d
d
d

조이!


반복적 인 호출을 수행하고 성능이 우려되는 경우이 테스트는 BASH 방법이 sed 및 다른 외부 프로세스를 포크하는 것보다 ~ 15 배 빠르다는 것을 보여줍니다.

hello=123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X

P1=$(date +%s)

for i in {1..10000}
do
   echo $hello | sed s/X//g > /dev/null
done

P2=$(date +%s)
echo $[$P2-$P1]

for i in {1..10000}
do
   echo ${hello//X/} > /dev/null
done

P3=$(date +%s)
echo $[$P3-$P2]

[[:digit:]]패턴으로 사용하십시오 (더블 괄호 참고).

$ hello=ho02123ware38384you443d34o3434ingtod38384day
$ echo ${hello//[[:digit:]]/}
howareyoudoingtodday

답변을 요약하고 싶었습니다 (특히 @ nickl-의 https://stackoverflow.com/a/22261334/2916086 ).

참고 URL : https://stackoverflow.com/questions/13043344/search-and-replace-in-bash-using-regular-expressions

반응형