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 acho que não consigo fazer com que cut funcione.

    
por tarabyte 30.12.2015 / 05:49

3 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 como em uma declaração case .

Também é possível usar correspondência regex POSIX:

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 da compatibilidade sh :

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

Como alternativa, se você estiver abusando do idioma:

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

(Este if / case / esac / then form na verdade é útil em algumas situações, como ao criar uma whitelist / blacklist incremental.)

Versão mais curta:

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

Muitos scripts sh usam expr , mas 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 uma regex ancorada (como grep, mas sempre com um ^ prefixado). Portanto, tenha cuidado ao passar uma variável como correspondência.

    
por 30.12.2015 / 06:52
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.

    
por 30.12.2015 / 06:15
0

Você pode usar a expansão do parâmetro bash :

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

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

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

$SearchString pode ser um literal: ele 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 \} . No primeiro formulário, a mesma consideração também se aplica a / .

    
por 12.01.2016 / 20:46

Tags