Bash regex espaço em branco antes do jogo

1

Estou tentando corresponder uma linha em um arquivo de texto com

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

Eu também tentei em vez de / s usar / A e / b alguns exemplos de coisas que eu tentei:

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]) ]];

Tudo isso corresponde a nada, se eu remover o primeiro para apenas fazer

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

ele combinará com o que eu queria corresponder, mas eu quero que ele combine com o espaço na frente, então ele não aceita seqüências de caracteres da linha média com ele também.

Exemplo de como uma partida se parece com o que eu quero:

OZBMN6HH1KI CGGAATGGGGGGGGGGGGGGGCGAGAATCTGAAATAGAGTGGTGACGTGCTGCGTTGACATAGGTCCTAGGGACCACCAG

O que estou fazendo de errado? Como posso fazer corresponder ␣CGGAAT ?

    
por Moopsish 10.11.2018 / 13:17

4 respostas

0

Substitua [\s] por [[:space:]] . Não sei qual é a origem do [\s] , mas os outros tiveram um equívoco semelhante. Portanto, a forma correta é

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

\A , \b e \s são Perl para "início da cadeia", "limite da palavra" e "um caractere de espaço em branco", respectivamente. (Veja a página perlre man ) Eles não são suportados nas expressões regulares estendidas que o Bash usa.

No ERE, o início da string é representado como ^ , e qualquer caractere de espaço em branco pode ser correspondido com [[:space:]] , ou se você quiser apenas corresponder a um espaço, com um espaço literal. Em alguns sistemas (pelo menos GNU), você pode representar o limite da palavra à esquerda com \< e o da direita com \> . Em outros, eles podem corresponder ao literal < e > .

No entanto, com espaços e barras invertidas, você tem problemas com o modo como o Bash analisa a expressão regular dentro da condicional. O espaço literal sem aspas termina o RE e a barra invertida ainda escapa dos caracteres. Para contornar isso, armazene o regex em uma variável primeiro:

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

ou, se \< funcionar e você quiser usar isso:

re='\<[CN]GGAAT'
if [[ $regel =~ $re ]]; then echo y; fi
    
por 10.11.2018 / 14:03
1

bash regexps em [[ =~ regex ]] são expressões regulares prolongadas POSIX. Em sistemas cujos regexps estendidos têm extensões além do que POSIX especifica (como regexps GNU que suportam \s (embora não dentro de expressões de colchetes) ou \b ), você só pode usá-los no bash como parte de uma expansão sem aspas (a menos que você vire na compatibilidade 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.

Se por \A você quer dizer início do assunto , então estamos falando de regexps compatíveis com perl ou perl, que são novamente diferentes expressões regulares.

Os EREs padrão não têm um conceito de modo de várias linhas em que ^ pode corresponder no início do assunto, mas também após cada caractere de nova linha, como quando se usa perl do (?m) . Algumas implementações do ERE, como as do ast-open, o suportam como uma extensão ( [[ a =~ \Aa ]] funciona em ksh93), mas em qualquer caso esse modo de múltiplas linhas não seria o padrão, então você pode usar ^ em vez de \A .

Mesmo em perl , [\A] não corresponderia ao início do assunto . [...] destina-se a corresponder a um caractere (ou às vezes ao elemento de agrupamento). [\A] corresponderia em A ou \ em ERE ou A em REs perl. [\b] corresponderia em b ou \ em ERE e no caractere de retrocesso em perl RE. [\s] on s ou \ no ERE e o mesmo que \s (caractere de espaço em branco) no perl RE.

Se você quiser corresponder em [CN]G{2}A{2}T no início do assunto ( \A ) ou seguir um caractere que não seja de palavra ( \b ), com EREs padrão, você faria:

[[ $var =~ (^|[^[:alnum:]_])[CN]G{2}A{2}T ]]
    
por 10.11.2018 / 14:15
0

Você pode combinar um espaço com um espaço entre aspas:

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

Eu removi o [] em torno de caracteres únicos.

    
por 10.11.2018 / 13:38