선행 공백과 일치하는 Bash 정규식

선행 공백과 일치하는 Bash 정규식

텍스트 파일의 한 줄을 다음과 결합하려고 합니다.

if [[ ${regel} =~ ([\s][CN][G]{2}[A]{2}[T]) ]];

또한 /s 대신 /A 및 /b를 사용해 보았습니다. 시도해 본 몇 가지 예는 다음과 같습니다.

if [[ ${regel} =~ (\A[CN][G]{2}[A]{2}[T]) ]];
if [[ ${regel} =~ (\b[CN][G]{2}[A]{2}[T]) ]];
if [[ ${regel} =~ ([\A][CN][G]{2}[A]{2}[T]) ]];
if [[ ${regel} =~ ([\b][CN][G]{2}[A]{2}[T]) ]];

일치하는 항목이 없도록 첫 번째 항목을 제거하면

if [[ ${regel} =~ ([CN][G]{2}[A]{2}[T]) ]];

그것은 내가 일치시키길 원하는 것과 일치할 것이지만, 문자열을 중앙에 맞출 필요가 없도록 앞의 ​​공백과 일치하기를 원합니다.

내가 원하는 경기의 예:

OZBMN6HH1KI CGGAATGGGGGGGGGGGGGGGCGAGAATCTGAAATAGAGTGGTGACGTGCTGCGTTGACATAGGTCCTAGGGACCACCAG

내가 뭘 잘못했나요? 어떻게 일치시킬 수 있나요 ␣CGGAAT?

답변1

bash의 정규식은 [[ =~ regex ]]POSIX 확장 정규식입니다. 확장 정규 표현식이 POSIX에서 지정한 범위를 넘어 확장되는 시스템(예: \s대괄호 표현식 내에 있지는 않지만 지원하는 GNU 정규 표현식 \b)에서는 이를 bash에서 인용되지 않은 확장 부분으로만 사용할 수 있습니다(활성화하지 않는 한). bash-3.1 호환성):

[[ a =~ \ba ]]                    # returns false
[[ a =~ $(printf %s '\ba') ]]     # returns true on GNU systems
BASH_COMPAT=3.1; [[ a =~ '\ba' ]] # returns true on GNU systems
re='\ba'; [[ a =~ $re ]]          # returns true on GNU systems.

\A당신이 의미하는 경우주제 시작, 그러면 우리는 다른 정규식인 perl 또는 perl 호환 정규식에 대해 이야기하고 있습니다.

표준 ERE에는 여러 줄 패턴 개념이 없으며 ^제목의 시작 부분에서 일치할 수 있지만 perls를 사용할 때 와 같이 각 줄 바꿈 뒤에도 일치할 수 있습니다 (?m). 일부 ERE 구현(예: ast-open의 ERE 구현)은 이를 확장으로 지원하지만( ksh93에서 작동) 어쨌든 여러 줄 모드는 기본 모드가 아니므로 를 사용하는 [[ a =~ \Aa ]]것이 더 좋습니다 .^\A

있어도 안 어울린다 perl.[\A]주제 시작. [...]문자(또는 때로는 조합 요소)와 일치하도록 설계되었습니다. ERE 또는 Perl RE [\A]에서 일치합니다 . AERE의 또는 및 Perl RE의 백스페이스 문자와 일치합니다. ERE에서 또는 Perl RE의 (공백 문자)와 동일합니다.\A[\b]b\[\s]s\\s

표준 ERE를 사용하여 [CN]G{2}A{2}T주제 시작 부분( \A) 또는 단어가 아닌 문자( ) 뒤의 a를 일치시키려면 다음을 수행할 수 있습니다.\b

[[ $var =~ (^|[^[:alnum:]_])[CN]G{2}A{2}T ]]

답변2

\A, \b그리고 \s각각 Perl의 "문자열 시작", "단어 경계" 및 "공백 문자"입니다. (보다perlre매뉴얼 페이지) Bash에서 사용하는 확장 정규식에서는 지원되지 않습니다.

ERE에서 문자열의 시작은 ^공백 문자와 일치할 수 있는 로 표시 [[:space:]]되거나, 공백만 일치시키려는 경우 리터럴 공백으로 표시됩니다. 일부 시스템(적어도 GNU)에서는 왼쪽 단어 경계를 로 \<, 오른쪽 단어 경계를 로 표시할 수 있습니다 \>. 다른 경우에는 <리터럴 및 와 일치 할 수 있습니다 >.

그러나 공백과 백슬래시를 사용하면 Bash가 조건에서 정규식을 구문 분석하는 방법에 문제가 발생합니다. 따옴표가 없는 문자 그대로의 공백은 RE를 종료하고 백슬래시는 여전히 이스케이프 문자입니다. 이 문제를 해결하려면 먼저 정규식을 변수에 저장하십시오.

re=' [CN]GGAAT'
if [[ $regel =~ $re ]]; then echo y; fi

또는 \<작동하고 사용하려는 경우:

re='\<[CN]GGAAT'
if [[ $regel =~ $re ]]; then echo y; fi

답변3

[\s]사용. . . 교체 [[:space:]]. 그 유래가 무엇인지는 잘 모르겠습니다 [\s]만,다른 사람비슷한 오해가 있었습니다. 따라서 올바른 형태는

>if [[ ${regel} =~ ([[:space]][CN][G]{2}[A]{2}[T]) ]];

답변4

공백을 인용된 공백과 일치시킬 수 있습니다.

if [[ ${regel} =~ ' '[CN]G{2}A{2}T  ]]

[]주변의 단일 문자를 제거했습니다 .

관련 정보