bash 조건식 및 백 슬래시 이스케이프

Oct 30 2020

이 동작을 이해하기가 정말 어렵습니다.

stackExchange@test:~$ if [[ "two words" =~ \bwords ]]; then echo hi; fi; #(I'd expect this one worked) stackExchange@test:~$ if [[ "two words" =~ \\bwords ]]; then echo hi; fi; #(or at least this one...)
stackExchange@test:~$ if [[ "two words" =~ \\\bwords ]]; then echo hi; fi; stackExchange@test:~$ if [[ "two words" =~ \\\\bwords ]]; then echo hi; fi;
stackExchange@test:~$ put_in_a_variable=\\bwords stackExchange@test:~$ if [[ "two words" =~ $put_in_a_variable ]]; then echo hi; fi; hi stackExchange@test:~$

내 변수가 포함 \bword하고 조건식의 패턴 섹션에서 확장 되었음을 이해 하지만 인라인 쉘 이스케이프를 사용하여 동일한 동작을 달성하는 것이 불가능 해 보이는 이유를 정말로 이해할 수 없습니다.

나는 같은 것을하고 싶지 않다 if [[ "two words" =~ $(echo \\bwords) ]]; then echo hi; fi;; 너무 이상한...

고마워,
프란체스코

답변

2 user414777 Oct 30 2020 at 01:33

의 정규식 부분에서 백 슬래시의 효과는 다음 문자 [[ str =~ rex ]]인용 하는 것입니다 (작은 인용 부호로 묶는 것과 동일). bash가 문자 일치를 수행하도록 지시합니다 (1). 때문에 b특별하지 않다, \b단지로 바뀔 것이다 b, 그러나 '\', "\\"또는 \\로 바뀝니다 \\리터럴 백 슬래시를 일치하기 위해 :

[[ abwords =~ \bwords ]] && echo "<$BASH_REMATCH>" <bwords> [[ 'a\bwords' =~ \\bwords ]] && echo "<$BASH_REMATCH>"
<\bwords>
# conversely, '|' is just like \|
[[ 'a|words' =~ a'|'words ]] && echo "<$BASH_REMATCH>"
<a|words>

정규식을 변수에 넣는 아이디어는 괜찮습니다. 대안은 래퍼 함수를 ​​사용하는 것입니다.

rematch() [[ $1 =~ $2 ]] if rematch 'two words' '\bwords\b'; then echo "<$BASH_REMATCH>"
fi
<words>

(1) 그 설명 된대로 수동 :

패턴의 모든 부분을 인용하여 인용 된 부분을 문자열로 일치시킬 수 있습니다.

셸에서 따옴표로 묶인 문자 는 실제로 특별히 표시되어 있으므로 구문 분석기에 의한 후속 처리는 문자열의 일부가 따옴표로 묶 였는지 또는 인용되지 않았는 지에 따라 결정을 내릴 수 있습니다.