Como verificar se uma string contém uma substring no Bash

How Check If String Contains Substring Bash



A questão é: como verificar se uma string contém uma substring no Bash. A resposta é: use a correspondência de padrões. Isso dá origem a outra questão, que é: o que é correspondência de padrões? Bem, uma frase em uma frase tem certas características. É por isso que difere de outras frases na mesma frase ou em outras frases. As características podem ser codificadas como um padrão. Dessa forma, uma determinada frase em uma string pode ser identificada. Este artigo explica como identificar uma substring específica em uma string maior, substituir a substring correspondida por outra substring e localizar qualquer substring em uma string maior por índice. No entanto, antes de mergulhar nas explicações, é preciso relembrar as diferentes maneiras como uma corda é estabelecida no Bash.

String por espaços de fuga

Uma string pode ser construída substituindo cada espaço pela sequência de escape do espaço, ‘’; como em:







myVar= Turismo no Egito é um do país 's principais econômicas indústrias.
jogou fora $ myVar

O resultado é:



O turismo no Egito é uma das principais indústrias econômicas do país.



Nota: o apóstrofo também usou a sequência de escape de espaço.





Sequência por citações simples

O programador tem tempo para escapar de todos os espaços em uma string? Não. Portanto, usar duas aspas simples para delimitar uma string é melhor; tal como:

myVar='Turismo no Egito é um do país' 'principais indústrias econômicas. '

Uma string entre aspas simples não permite a expansão (substituição com seu efeito) de qualquer sequência de escape. Felizmente, se duas strings forem codificadas uma ao lado da outra, elas serão consideradas uma única string. Uma sequência de escape pode ser inserida no meio, como feito acima. A sequência de escape seria expandida. Portanto, a saída se torna:



O turismo no Egito é uma das principais indústrias econômicas do país.

String por aspas duplas

Com aspas duplas, as sequências de escape também não são expandidas, mas as variáveis ​​são expandidas. O código a seguir ilustra isso:

myVar= Turismo no Egito é um do país 's principais econômicas indústrias.
jogou fora $ myVar

O resultado é:

O turismo no Egito é uma das principais indústrias econômicas do país.

Nota: o apóstrofo também usou a sequência de escape de espaço.

Neste artigo, o principal tipo de string considerado é a string entre aspas simples.

Fundamentos da expressão regular

Regex

Considere esta string:

Este mundo não é realmente nossa casa.

Deixe que o mundo seja a base de interesse. Então, a string grande (string inteira) é chamada de string alvo ou simplesmente, o alvo. O ‘mundo’ entre aspas é chamado de expressão regular ou simplesmente regex. O conteúdo, mundo, é o padrão, neste caso.

Correspondência Simples

No código a seguir, se a palavra ‘mundo’ for encontrada no destino, diríamos que a palavra foi correspondida.

p='Este mundo não é realmente nossa casa.'
reg='mundo'
E se [[ $ str= ~$ reg ]];então
jogou foraencontrado
outro
jogou foranão encontrado
ser

= ~, que é o operador de atribuição seguido por ~, é chamado de operador de vinculação. A condição verifica se o padrão é compatível com a string de destino. Se uma substring correspondente ao padrão for encontrada no destino, a instrução echo exibe found. Se não for encontrado, a instrução echo echoes not found. A saída para este código é:

encontrado

Como o padrão, mundo, é encontrado no alvo. Observe que o espaço delimitador após [[e antes]] foi mantido.

Padrão

No código acima, 'mundo' entre aspas é a regex, enquanto o próprio mundo é o padrão. Este é um padrão simples. No entanto, a maioria dos padrões não é tão simples. Um padrão é uma caracterização de uma substring a ser encontrada. E assim, o padrão Bash usa certos metacaracteres. Um metacaractere é um personagem sobre outros personagens. Por exemplo, o padrão Bash usa os seguintes metacaracteres:

^ $ . * +? () [] {} |

Uma expressão regular também pode ser digitada nos colchetes duplos da condição. Mas não precisa estar entre aspas. Portanto, neste caso, é literalmente um padrão.

Classes de personagens

Colchetes

A saída do seguinte código é encontrada, o que significa que ocorreu uma correspondência:

p='O gato entrou na câmara.'
E se [[ $ str= ~[cbr]no]];então
jogou foraencontrado
ser

O padrão, [cbr] em correspondeu cat, que começa com 'c' e que continua e termina com at. [cbr] em significa, corresponder 'c' ou 'b' ou 'r' seguido por at.

A saída do seguinte código é encontrada, o que significa que ocorreu uma correspondência:

p='O morcego entrou na câmara.'
E se [[ $ str= ~[cbr]no]];então
jogou foraencontrado
ser

O padrão, [cbr] em combinou morcego, que começa com 'b', e que continua e termina com em. [cbr] em significa, corresponder 'c' ou 'b' ou 'r' seguido por at.

A saída do seguinte código é encontrada, o que significa que ocorreu uma correspondência:

p='O rato entrou na câmara.'
E se [[ $ str= ~[cbr]no]];então
jogou foraencontrado
ser

O padrão, [cbr] em combinou rato, que começa com 'r', e que continua e termina com em.

Nos exemplos de código acima, o programador não sabe se existe gato, morcego ou rato na string de destino. Mas, ele sabe que a substring começa com 'c' ou 'b' ou 'r', então continua e termina com at. Os colchetes em um padrão permitem que diferentes caracteres possíveis correspondam a um caractere em uma posição em relação a outros no destino. Portanto, os colchetes contêm um conjunto de caracteres, dos quais um corresponde a uma substring. Finalmente, é a substring completa que é correspondida.

Gama de personagens

No código acima [cbr] é uma classe. Mesmo que ‘c’ ou ‘b’ ou ‘r’ corresponda a um único caractere, se o seguinte imediatamente não corresponder, o padrão não corresponderá a nada.

Bem, existem certos intervalos que formarão uma classe. Por exemplo, 0 a 9 dígitos formam a classe, [0-9] com 0 e 9 incluídos. 'A' minúsculo a 'z' forma a classe [a-z] com 'a' e 'z' incluídos. Letras maiúsculas de 'A' a 'Z' formam a classe [A-Z] com 'A' e 'Z' incluídos. De uma classe, é um dos caracteres que corresponderia a um caractere na string.

O código a seguir produz uma correspondência:

E se [[ 'ID8id'= ~[0-9] ]];então
jogou foraencontrado
ser

Desta vez, o destino é uma string literal na condição. 8, que é um dos números possíveis dentro do intervalo, [0-9], correspondeu a 8 na sequência, 'ID8id'. O código acima é equivalente a:

E se [[ 'ID8id'= ~[0123456789] ]];então
jogou foraencontrado
ser

Aqui, todos os números possíveis foram escritos no padrão, portanto, não há hífen.

No código a seguir, uma correspondência é obtida:

E se [[ 'ID8iD'= ~[a-z] ]];então
jogou foraencontrado
ser

A correspondência é entre 'i' minúsculo do intervalo, [a-z], e 'i' minúsculo da string de destino, 'ID8iD'.

Lembre-se: o intervalo é uma classe. A classe pode fazer parte de um padrão maior. Portanto, em um padrão, o texto pode estar na frente e / ou depois da aula. O código a seguir ilustra isso:

E se [[ 'ID8id é o identificador'= ~ ID[0-9]Eu iria ]];então
jogou foraencontrado
ser

A saída é: encontrado. ‘ID8id’ do padrão correspondeu a ‘ID8id’ na string de destino.

Negação

A correspondência não é obtida a partir do seguinte código:

E se [[ '0123456789101112'= ~[^0-9] ]];então
jogou foraencontrado
outro
jogou foranão encontrado
ser

O resultado é:

não encontrado

Sem ^ na frente do intervalo, dentro dos colchetes, zero do intervalo teria correspondido ao primeiro zero da string de destino. Portanto, ^ na frente de um intervalo (ou caracteres opcionais) nega a classe.

O código a seguir produz uma correspondência porque a condição diz: corresponder a qualquer caractere diferente de dígito em qualquer lugar do destino:

E se [[ 'ABCDEFGHIJ'= ~[^0-9] ]];então
jogou foraencontrado
outro
jogou foranão encontrado
ser

Portanto, a saída é: encontrado.

[^ 0-9] significa um não dígito, então [^ 0-9] é a negação de [0-9].

[^ a-z] significa uma letra não minúscula, então [^ a-z] é a negação de [a-z].

[^ A-Z] significa uma letra não maiúscula, então [^ A-Z] é a negação de [A-Z].

Outras negações estão disponíveis.

O ponto final (.) No padrão

O ponto (.) No padrão corresponde a qualquer caractere, incluindo ele mesmo. Considere o seguinte código:

E se [[ '6759WXY.A3'= ~ 7.9W.Y.A]];então
jogou foraencontrado
ser

A saída do código é encontrada porque os outros caracteres correspondem. Um ponto corresponde a ‘5’; outro ponto corresponde a ‘X’; e o último ponto corresponde a um ponto.

Alternância de correspondência

Considere esta frase para uma string de destino:

A gaiola possui pássaros de diferentes tipos.

Alguém pode querer saber se este alvo tem pombo, pavão ou águia. O seguinte código pode ser usado:

p='A jaula tem pavões de diferentes tipos.'
E se [[ $ str= ~ pombo|pavão|Águia]];então
jogou foraencontrado
outro
jogou foranão encontrado
ser

A saída é, encontrado. O metacaractere de alternância, | foi empregado. Pode haver duas, três, quatro e mais alternativas. O que correspondeu neste código é ‘peacock’.

Agrupamento

No seguinte padrão, parênteses foram usados ​​para agrupar caracteres:

um palco (dançarino)

O grupo aqui é um dançarino de palco rodeado pelos metacaracteres (e). (dançarino) é um subgrupo, enquanto um palco (dançarino) é todo o grupo. Considere o seguinte:

O (dançarino é incrível)

Aqui, o subgrupo ou substring é, dançarino é incrível.

Substrings com partes comuns

Uma parte interessada é uma pessoa com interesse em um negócio. Imagine uma empresa com um site, stake.com. Imagine que uma das seguintes strings de destino esteja no computador:

O site, stake.com, é para os negócios .;

Existe a parte interessada .;

A parte interessada trabalha para a stake.com .;

Deixe qualquer uma dessas strings ser o alvo. O programador pode querer saber se stake.com ou stakeholder está em qualquer string de destino. Seu padrão seria:

stake.com | stakeholder

usando alternância.

aposta foi digitada duas vezes nas duas palavras. Isso pode ser evitado digitando o padrão da seguinte maneira:

aposta (.com | titular)

.com | holder é o subgrupo neste caso.

Nota: o uso do caractere de alternância neste caso. stake.com ou stakeholder ainda será pesquisado. A saída do seguinte código é encontrada:

p='O site, stake.com, é para o negócio.'
E se [[ $ str= ~ aposta(.com|suporte) ]];então
jogou foraencontrado
ser

A substring correspondida aqui é stake.com.

O array predefinido BASH_REMATCH

BASH_REMATCH é uma matriz predefinida. Suponha que um padrão tenha grupos. Todo o grupo correspondido, vai para a célula para o índice 0 desta matriz. O primeiro subgrupo correspondido vai para a célula do índice 1; o segundo subgrupo foi correspondido, vai para a célula do índice 2 e assim por diante. O código a seguir mostra como usar esta matriz:

p='O dançarino de palco chegou.'
E se [[ $ str= ~ estágio (dançarino) ]];então
jogou foraencontrado
ser

paraeuno $ {! BASH_REMATCH [@]};Faz
printf '$ {BASH_REMATCH [i]}, '
feito
jogou fora

O resultado é:

encontrado
dançarina de palco, dançarina,

Todo o grupo é dançarino de palco. Existe apenas um subgrupo, que é dançarino.

Nota: o espaço no padrão foi escapado.

Correspondência de independência de maiúsculas / minúsculas

A correspondência, conforme explicado acima, diferencia maiúsculas de minúsculas. A correspondência pode ser feita independentemente do caso. Isso é ilustrado no seguinte código:

lojas -snocasematch

p='Nós gostamos de boa música.'
E se [[ $ str= ~ GoOd]];então
jogou foraencontrado
ser

lojas -vocênocasematch

A saída é: encontrado. O padrão é GoOd. A substring correspondida é 'boa'. Observe como a opção nocasematch foi habilitada no início do segmento de código e desabilitada no final do segmento de código.

Comprimento de uma corda

A sintaxe para obter o comprimento de uma string é:

$ {# PARAMETER}

Exemplo:

p='Nós gostamos de boa música.'
jogou fora $ {# str}

O resultado é: 19.

Redução de cordas

As sintaxes para redução de string são:

$ {PARAMETER: OFFSET}
$ {PARAMETER: OFFSET: LENGTH}

onde a contagem para OFFSET começa do zero.

O exemplo a seguir mostra como remover os primeiros 11 caracteres de uma string:

p='Eu sempre danço boa música.'
jogou fora $ {str: 10}

O resultado é:

uma boa música.

Contando para LENGTH, começa a partir do próximo caractere. O código a seguir mostra como uma parte da string pode ser permitida:

p='Eu sempre danço boa música.'
jogou fora $ {str: 10: 6}

O resultado é:

ance t

Os primeiros 11 caracteres foram removidos; os próximos 6 caracteres foram permitidos, e o resto dos personagens foram removidos automaticamente.

Pesquisar e substituir

Quando uma substring é encontrada, ela pode ser substituída por outra substring. As sintaxes para isso são:

Onde=$ {PARAMETER / PATTERN / REPLACEMENT}
Onde=$ {PARAMETER // PATTERN / REPLACEMENT}
Onde=$ {PARAMETER / PATTERN}
Onde=$ {PARAMETER // PATTERN}

Para a primeira sintaxe com barra simples, apenas a primeira correspondência é substituída. Exemplo:

p='Há um rato, um morcego e um gato, na câmara.'
direito=$ {str / [cbr] at / big cow}
jogou fora $ str
jogou fora $ ret

O resultado é:

Há um rato, um morcego e um gato na câmara.
Há uma grande vaca, um morcego e um gato na câmara.

Para a segunda sintaxe com barras duplas, todas as ocorrências da correspondência são substituídas. Exemplo:

p='Há um rato, um morcego e um gato na câmara.'
direito=$ {str // [cbr] at / big cow}
jogou fora $ str
jogou fora $ ret

O resultado é:

Há um rato, um morcego e um gato na câmara.
Há uma vaca grande, uma vaca grande e uma vaca grande na câmara.

Para a terceira sintaxe com barra simples, não há substituição para a primeira e única correspondência.

Além disso, a primeira substring encontrada é excluída. Exemplo:

p='Há um rato, um morcego e um gato na câmara.'
direito=$ {str / [cbr] em}
jogou fora $ str
jogou fora $ ret

Para a quarta sintaxe com barras duplas, não há substituição para todas as correspondências. Além disso, todas as substrings encontradas são excluídas. Exemplo:

p='Há um rato, um morcego e um gato na câmara.'
direito=$ {str // [cbr] em}
jogou fora $ str
jogou fora $ ret

O resultado é:

Há um rato, um morcego e um gato na câmara.
Há um, um e um na câmara.

Conclusão

Para verificar se uma string possui uma substring no Bash, a correspondência de padrões deve ser usada. A correspondência de padrão não ocorre apenas na condição de colchetes duplos, [[. . . ]]. Também pode ocorrer na expansão do parâmetro, com seu $ {. . .}. Com a expansão dos parâmetros, é possível obter uma substring por índices.

O que foi apresentado neste artigo são os pontos mais críticos na correspondência de padrões. Há mais! No entanto, o que o leitor deve estudar a seguir é a expansão do nome de arquivo.