내가 아는 한, \b
bash는 "단어 경계"를 나타내는 메타 시퀀스를 지원하지 않습니다.
if [[ $foo =~ .*\bWORD\b.* ]]; then
이 기능이 지원되지 않는 이유가 있나요?
bash에 대한 패치/풀 요청을 작성한다고 상상해 보세요. 구현될 수 없는 이유가 있습니까 \b
("이 기능이 마음에 들지 않습니다" 등 제외)?
답변1
~에 따르면bash
매뉴얼 페이지, 이 =~
연산자는 POSIX 정규식 함수를 사용하는 것으로 보입니다.
연산자를 사용하면
=~
오른쪽 문자열은 POSIX 확장 정규식 패턴으로 처리되어 그에 따라 일치됩니다(POSIXregcomp
및 일반적으로 설명된 인터페이스 사용).regexec
regex(3)
메타 \b
시퀀스는Perl 정규식 구문POSIX의 일부가 아니므로 Bash에서 사용하는 라이브러리는 이를 지원하지 않는 것 같습니다. 따라서 Bash에서 이를 지원한다는 것은 라이브러리를 변경하는 것을 의미할 수 있으며, 이는 종종 심각한 부작용을 낳습니다.
이는 순전히 문법적 요소를 수용하기 위해 수행된 것 같지 않습니다.
답변2
먼저 Bash에 자체 RE 구현이 있는지, 아니면 시스템 라이브러리의 RE 구현을 사용하는지 확인하세요.
하지만 그렇습니다. \b
일반적으로 Perl 정규식에서 비롯된 표준 정규식에서는 사용할 수 없는 다른 확장도 많이 포함하고 있습니다. GNU 시스템은 \s
공백과 단어 문자를 지원하는 것으로 보이지만 숫자는 지원 \w
하지 않습니다 \d
. 왜 그 이상한 것들을 선택하기로 결정했는지는 모르겠지만, 전반적으로,모두Perl RE 기능은 RE 엔진을 더욱 복잡하게 만들 수 있으며 Perl 팬은 이를 좋아하지만 많은 표준 도구 작성자는 이를 원하지 않을 수 있습니다. 그러다가 전부는 아니고 이것저것 추가하기 시작하면 어디에 선을 그어야 할지 결정하는 것이 문제가 됩니다.
어쨌든 단어 테두리는 처음부터 비표준입니다. 일부 시스템에서는 \<
및 가 \>
왼쪽 및 오른쪽 경계선에 적용되어야 하지만 FreeBSD 및 Mac에서는 [[:<:]]
및 가 필요합니다 [[:>:]]
.
공교롭게도 @steeldriver가 언급한 것처럼 \b
적어도 제가 테스트했을 때 GNU에서도 작동하는 것 같습니다. Bash에서는 쉘의 구문 분석 프로세스로 인해 특수 문자가 난독화되는 것을 방지하기 위해 먼저 RE를 변수에 저장해야 합니다.
$ re='\bWORD\b'; if [[ WORD =~ $re ]]; then echo y; else echo n; fi
y
$ re='\<WORD\>'; if [[ WORD =~ $re ]]; then echo y; else echo n; fi
y
$ re='\bWORD\b'; if [[ WORDLESS =~ $re ]]; then echo y; else echo n; fi
n
$ re='\<WORD\>'; if [[ WORDLESS =~ $re ]]; then echo y; else echo n; fi
n