Substring em string no bash?

0

Qual é o equivalente da instrução python no bash:

if "mystr" in "a long string with mystring in it":
    print("found string")

O deslocamento em número de caracteres NÃO pode ser considerado constante, então eu não acho que posso começar cuta trabalhar.

tarabyte
fonte

Respostas:

2

Use correspondência de caractere curinga. Para bash especificamente:

if [[ $longstring == *mystr* ]]; then

if [[ $longstring == *"my string"* ]]; then

if [[ $longstring == *"$matchstr"* ]]; then

No [[operador, o lado esquerdo é expandido literalmente (isto é, sem a necessidade de aspas duplas), enquanto as partes não nomeadas do lado direito são tratadas como curingas - basicamente as mesmas regras de cotação que em uma caseinstrução.

É possível usar a correspondência regex POSIX também:

if [[ $longstring =~ mystr ]]; then

if [[ $longstring =~ "my string" ]]; then

if [[ $longstring =~ "$matchstr" ]]; then

Novamente, as partes citadas do lado direito são correspondidas literalmente, enquanto as partes não citadas são correspondidas como operadores regex.


Se você precisar de compatibilidade sh :

case $longstring in
    *mystr*)
        echo yes;;
    *"$matchstr"*)
        echo yes again!;;
    *)
        echo no;;
esac

Alternativamente, se você estiver abusando do idioma:

if case $longstring in
    *mystr*) true;;
    *"$matchstr"*) true;;
    *) false;;
esac; then
    ...
fi

(Este if / case / esac /, em seguida, formulário é realmente útil em algumas situações, como quando se faz uma lista de desbloqueio / blacklist.)

Versão mais curta:

if ! case $longstring in *"$matchstr"*) !; esac; then
    echo "It matched!"
fi

Muitos scripts sh usam, exprmas não é um shell embutido, portanto, um pouco mais lento:

if expr match "$longstring" ".*mystr"; then
    ...
fi

Neste caso (como expr não pode ver diferenças na cotação), o parâmetro "match" inteiro é interpretado como um regex ancorado (como grep mas sempre com um ^prefixo). Portanto, tenha cuidado ao passar uma variável como a correspondência.

grawity
fonte
1

Isso fará isso:

#! /bin/bash

X=`echo "a long string with mystring in it" | grep "mystr" | wc -l`
if [ $X -gt 0 ]
then
        echo "found string";
fi

A idéia aqui é que "echo" configura a string, grep procura pela substring na string passada para ela, e wc -l retorna o número de linhas em que a string foi encontrada - então, 0 ou 1.

davidgo
fonte
Achei isso também: askubuntu.com/questions/299710/…
tarabyte
Eu estava apenas trabalhando em algo assim para uma resposta mais sofisticada - agora eu criei o seguinte 1 liner (que é indiscutivelmente mais próximo do que você queria): echo "uma longa string com mystring nele" | grep -q "mystr" && echo "encontrado string" - mas seu caminho é mais eficiente.
davidgo
1
ahhhh! grep retorna 0 se a correspondência for encontrada. muito mais legível
tarabyte
1
Sim, isso significa que você pode simplificá-lo paraif echo ... | grep -q ...; then
Grawity
0

Você pode usar a bashexpansão de parâmetro:

if [ "${TestString/$SearchString/}" == "$TestString" ]; then echo Found; fi

ou se você quiser uma expressão compatível com Bourne:

if [ "${TestString#*$SearchString}" == "$TestString" ]; then echo Found; fi

$SearchStringpode ser um literal: pode conter espaços, seja um literal ou uma variável, e uma variável pode conter }, mas em um literal deve ser escapado como \}. Na primeira forma, a mesma consideração também se aplica a /.

AFH
fonte