Bash 스크립트의 정규식에서 ASCII 코드를 일치시키는 데 문제가 있습니다.
내 페이로드는 다음과 같습니다payload='#1243669, start 2018-12-17 16:32:50 CET'
내 이전 정규식은 다음과 같습니다. regold='(#[^,]+),'
내 새 정규식은 다음과 같습니다.regnew='(#[^\x2c]+)\x2c'
셸에서 테스트하면 regex101.com에서는 작동하지만 새 정규식이 작동하지 않는 것으로 확인됩니다.
root@test# payload='#1243669, start 2018-12-17 16:32:50 CET'
root@test# regold='(#[^,]+),'
root@test# regnew='(#[^\x2c]+)\x2c'
root@test# if [[ $payload =~ $regold ]]; then echo yes; fi
yes
root@test# if [[ $payload =~ $regnew ]]; then echo yes; fi
편집하다:
질문은 PCRE 표현식이 지원되지 않는다고 bash에 알려줌으로써 부분적으로 대답됩니다. 그래서 정규식을 다음으로 옮겼습니다.
root@test# regex=$'(\x23[^\x2c]+)\x2c[[:space:]]start[[:space:]][[:digit:]]{4}\x2d[[:digit:]]{2}\x2d[[:digit:]]{2}[[:space:]]([^[:space:]]+)[[:space:]][^\x2c]+\x2c[^\x2c]+\x2c[[:space:]](captureme)'
root@test# pattern='Message #1243669, start 2018-12-17 16:32:50 CET, duration 20, captureme'
다시 말하지만, 내 표현은 regex101에서 훌륭하게 작동합니다. 여기에 예가 있습니다.https://regex101.com/r/g4UsUN/1
표현식은 지금까지 진행됩니다: ... [[:space:]][^\x2c]+ ... 하지만 \x2c를 추가하면 bash에 약간의 어려움이 있습니다.
어떻게 되어가나요?
답변1
에서는 bash
코드의 리터럴 문자에 대해 16진수 코드를 삽입할 수 있습니다 $'\xHH'
. bash
그렇지 않으면 문자열에서 인식되지 않으며 정규식은 , 또는 가 [^\x2c]
아닌 모든 문자와 일치합니다 . 표현식을 테스트하고 있는 웹사이트는 PCRE 정규식 엔진을 사용할 수 있습니다. 그런 용도는 아니며 POSIX 확장 정규식(사이트에서 지원하지 않는 것 같음)을 사용합니다. 이는 또한 숫자, 공백 문자, 미리보기 등과 같이 PCRE에서 사용하는 다른 정규식 구문이 지원되지 않음을 의미합니다.\
x
2
c
regex101.com
bash
bash
\d
\s
POSIX 정규식(기본 및 확장)은 시스템의 re_format(7)
매뉴얼( man 7 re_format
) 및 다음을 통해 문서화해야 합니다.POSIX 표준.
그러므로
regnew=$'#[^\x2c]+\x2c'
(괄호는 사용하지 않는 것 같아 제거했습니다.) 이스케이프 시퀀스는 문자열이 변수에 할당되기 전에 확장 되고 bash
정규식에서 특별한 의미를 가질 수 있는 문자로 확장될 수 있으므로 이스케이프 시퀀스가 리터럴 값과 일치하도록 주의해야 합니다. 예를 들어 리터럴 점을 일치시키려면 \x2e
(점 문자) 앞에 \\
( )를 붙여야 할 수 있습니다.\\\x2e
bash
매뉴얼 에서 :
이 형태의 단어는
$'string'
특별히 처리됩니다. 단어는 ANSI C 표준에 지정된 대로 대체된 백슬래시 이스케이프 문자를 사용하여 문자열로 확장됩니다. 백슬래시 이스케이프 시퀀스가 있는 경우 다음과 같이 디코딩됩니다.[...]
\xHH
HH
값이 16진수 값(1자리 또는 2자리의 16진수)인 8비트 문자
를 사용하면 $'...'
쉘이 인식하는 다른 이스케이프 시퀀스도 대체하게 됩니다.