Cómo verificar si una cadena contiene una subcadena en Bash

Tengo una cadena en Bash:

string="My string"

¿Cómo puedo probar si contiene otra cadena?

if [ $string ?? 'foo' ]; then
  echo "It's there!"
fi

Dónde ?? es mi operador desconocido. Yo uso echo y grep?

if echo "$string" | grep 'foo'; then
  echo "It's there!"
fi

Eso parece un poco torpe.

preguntado Oct 23 '08, 10:10

Hola, si las cadenas vacías son falsas, ¿por qué lo consideras torpe? Fue la única forma que funcionó para mí, a pesar de las soluciones propuestas. -

Puede utilizar el expr comando aquí -

Aquí hay uno para conchas posix: stackoverflow.com/questions/2829613/… -

26 Respuestas

Puedes usar Respuesta de Marcus (* comodines) fuera de una declaración de caso, también, si usa corchetes dobles:

string='My long string'
if [[ $string == *"My long"* ]]; then
  echo "It's there!"
fi

Tenga en cuenta que los espacios en la cuerda de la aguja deben colocarse entre comillas dobles, y el * los comodines deben estar fuera. También tenga en cuenta que se utiliza un operador de comparación simple (es decir, ==), no el operador de expresiones regulares =~.

Respondido 17 Abr '20, 02:04

También tenga en cuenta que puede revertir la comparación simplemente cambiando a! = En la prueba. ¡Gracias por la respuesta! - quinn taylor

@Jonik: Puede que te pierdas el asunto o lo tengas como #!/bin/sh. Probar #!/bin/bash en lugar de. - dennis williamson

Deje un espacio entre los corchetes y el contenido. - Paul Price

No es necesario citar variables dentro de [[]]. Esto funcionará igual de bien: [[$ string == $ aguja ]] && echo encontrado - orwellófilo

@Orwellophile ¡Cuidadoso! Solo puede omitir las comillas dobles en el primer argumento para [[. Vea ideone.com/ZSy1gZ - nyuszika7h

Si prefiere el enfoque de expresiones regulares:

string='My string';

if [[ $string =~ "My" ]]; then
   echo "It's there!"
fi

respondido 19 nov., 20:18

Tuve que reemplazar una expresión regular egrep en un script bash, ¡esto funcionó perfectamente! - explosión_quesoduro

El =~ el operador ya busca una coincidencia en toda la cadena; la .*Los de aquí son ajenos. Además, las comillas son generalmente preferibles a las barras diagonales inversas: [[ $string =~ "My s" ]] - Bukzor

@bukzor Quotes dejó de funcionar aquí a partir de Bash 3.2+: tiswww.case.edu/php/chet/bash/FAQ E14). Probablemente sea mejor asignar una variable (usando comillas) y luego comparar. Como esto: re="My s"; if [[ $string =~ $re ]] - Seanf

Prueba si lo hace NO contener una cadena: if [[ ! "abc" =~ "d" ]] es verdad. - KrisWebDev

Tenga en cuenta que el orden en el que se realiza la prueba es importante. La salida de la siguiente línea de código se reenviará 2. number=2; if [[ "1, 2, 4, 5" = *${number}* ]]; then echo forward $number; fi; if [[ *${number}* = "1, 2, 4, 5" ]]; then echo backwards $number; fi; - Douwe van der Leest

No estoy seguro de usar una declaración if, pero puede obtener un efecto similar con una declaración de caso:

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac

Respondido 23 Oct 08, 13:10

Esta es probablemente la mejor solución ya que es portátil para posix shells. (también conocido como sin bashismos) - tecnosaurio

@technosaurus Me parece bastante extraño criticar "bashism" en una pregunta que solo tiene etiqueta bash :) - PÁGINAS

@PP No es tanto una crítica como la preferencia de una solución más universal sobre una más limitada. Tenga en cuenta que, años más tarde, la gente (como yo) pasará a buscar esta respuesta y puede que le guste encontrar una que sea útil en un ámbito más amplio que la pregunta original. Como dicen en el mundo del código abierto: "¡la elección es buena!" - carl smotricz

@technosaurus, FWIW [[ $string == *foo* ]] también funciona en algunas versiones sh compatibles con POSIX (p. ej. /usr/xpg4/bin/sh en Solaris 10) y ksh (> = 88) - maxschlepzig

Busybox ash no maneja asteriscos en [[ ... ¡el cambio de caja funcionó! - ray foss

stringContain variantes (compatibles o independientes del caso)

Como estas respuestas de Stack Overflow hablan principalmente sobre Asestar un golpe, He publicado un caso independiente Función Bash en la parte inferior de esta publicación ...

De todos modos, ahí está mi

Respuesta compatible

Como ya hay muchas respuestas que utilizan funciones específicas de Bash, hay una forma de trabajar con shells con menos funciones, como BusyBox:

[ -z "${string##*$reqsubstr*}" ]

En la práctica, esto podría dar:

string='echo "My string"'
for reqsubstr in 'o "M' 'alt' 'str';do
  if [ -z "${string##*$reqsubstr*}" ] ;then
      echo "String '$string' contain substring: '$reqsubstr'."
    else
      echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
  done

Esto fue probado bajo Bash, Dash, KornShell (ksh) y ceniza (BusyBox), y el resultado es siempre:

String 'echo "My string"' contain substring: 'o "M'.
String 'echo "My string"' don't contain substring: 'alt'.
String 'echo "My string"' contain substring: 'str'.

En una función

Como preguntó @EeroAaltonen, aquí hay una versión de la misma demostración, probada bajo los mismos shells:

myfunc() {
    reqsubstr="$1"
    shift
    string="$@"
    if [ -z "${string##*$reqsubstr*}" ] ;then
        echo "String '$string' contain substring: '$reqsubstr'.";
      else
        echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
}

Entonces:

$ myfunc 'o "M' 'echo "My String"'
String 'echo "My String"' contain substring 'o "M'.

$ myfunc 'alt' 'echo "My String"'
String 'echo "My String"' don't contain substring 'alt'.

Tenga en cuenta: tiene que escapar o entre comillas dobles y / o comillas dobles:

$ myfunc 'o "M' echo "My String"
String 'echo My String' don't contain substring: 'o "M'.

$ myfunc 'o "M' echo \"My String\"
String 'echo "My String"' contain substring: 'o "M'.

Función simple

Esto se probó en BusyBox, Dash y, por supuesto, Bash:

stringContain() { [ -z "${2##*$1*}" ]; }

Entonces ahora:

$ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi
no
$ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi
yes

... O si la cadena enviada pudiera estar vacía, como lo señaló @Sjlver, la función se convertiría en:

stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }

o como lo sugiere Comentario de Adrian Günterevitando -o interruptores:

stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ];};}

Función final (simple):

E invertir las pruebas para hacerlas potencialmente más rápidas:

stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}

Con cadenas vacías:

$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

Independiente del caso (¡solo Bash!)

Para probar cadenas sin preocuparse por el uso de mayúsculas y minúsculas, simplemente convierta cada cadena a minúsculas:

stringContain() {
    local _lc=${2,,}
    [ -z "$1" ] || { [ -z "${_lc##*${1,,}*}" ] && [ -n "$2" ] ;} ;}

Comprobar:

stringContain 'o "M3' 'echo "my string"' && echo yes || echo no
no
stringContain 'o "My' 'echo "my string"' && echo yes || echo no
yes
if stringContain '' ''; then echo yes; else echo no; fi
yes
if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

contestado el 25 de mayo de 20 a las 07:05

Esto sería aún mejor, si puede encontrar alguna forma de poner eso en una función. - Eero Aalton

@EeroAaltonen ¿Cómo encuentra mi función (nueva agregada)? - F.Hauri

¡Sé! encontrar . -nombre "*" | xargs grep "myfunc" 2> / dev / null - huevos

Esto es maravilloso porque es muy compatible. Sin embargo, hay un error: no funciona si la cadena del pajar está vacía. La versión correcta sería string_contains() { [ -z "${2##*$1*}" ] && [ -n "$2" -o -z "$1" ]; } Un pensamiento final: ¿la cadena vacía contiene la cadena vacía? La versión anterior cosas sí (debido a la -o -z "$1" parte). - Plata

+1. ¡Muy bien! Para mí, cambié el orden stringContain () {[-z "$ {1 ## * $ 2 *}"] && [-z "$ 2" -o -n "$ 1"]; }; "Buscar dónde" "Buscar qué". Trabaja en busybox. La respuesta aceptada anterior no funciona en busybox. - user3439968

Debe recordar que los scripts de shell son menos un lenguaje y más una colección de comandos. Instintivamente crees que este "lenguaje" requiere que sigas una if con un [ o con una [[. Ambos son solo comandos que devuelven un estado de salida que indica éxito o fracaso (como cualquier otro comando). Por esa razón usaría grep, y no el [ mando.

Solo haz:

if grep -q foo <<<"$string"; then
    echo "It's there"
fi

Ahora que estas pensando if como probar el estado de salida del comando que lo sigue (completo con punto y coma), ¿por qué no reconsiderar la fuente de la cadena que está probando?

## Instead of this
filetype="$(file -b "$1")"
if grep -q "tar archive" <<<"$filetype"; then
#...

## Simply do this
if file -b "$1" | grep -q "tar archive"; then
#...

El -q La opción hace que grep no genere nada, ya que solo queremos el código de retorno. <<< hace que el shell expanda la siguiente palabra y la use como entrada para el comando, una versión de una línea del << aquí documento (no estoy seguro de si esto es estándar o un basismo).

Respondido el 01 de enero de 20 a las 13:01

se les llama aquí cadenas (3.6.7) Creo que es bashismo alex.pilon

uno también puede usar Sustitución de procesos if grep -q foo <(echo somefoothing); then - larsr

Tenga en cuenta que echo no es portátil, si está pasando una variable, use printf '%s' "$string en lugar de. - nyuszika7h

El costo de esto es muy caro: hacer grep -q foo <<<"$mystring" implica 1 tenedor y es bashismo y echo $mystring | grep -q foo Implica 2 horquillas (una para la tubería y la segunda para correr /path/to/grep) - F.Hauri

@BrunoBronosky echo sin banderas aún puede tener problemas de portabilidad inesperados si la cadena de argumentos contiene secuencias de barra invertida. echo "nope\c" se espera que en algunas plataformas funcione como echo -e "nope" en algunos otros. printf '%s' "nope" vs printf '%s\n' 'nope\c' - triples

La respuesta aceptada es la mejor, pero como hay más de una forma de hacerlo, aquí hay otra solución:

if [ "$string" != "${string/foo/}" ]; then
    echo "It's there!"
fi

${var/search/replace} is $var con la primera instancia de search reemplazado por replace, si se encuentra (no cambia $var). Si intentas reemplazar foo por nada, y la cadena ha cambiado, entonces obviamente foo fue encontrado.

Respondido el 12 de junio de 13 a las 06:06

la solución de ephemient anterior:> `if [" $ string "! =" $ {string / foo /} "]; luego repita "¡Está ahí!" fi` es útil cuando se usa el shell de BusyBox ceniza. La solución aceptada no funciona con BusyBox porque algunas expresiones regulares de bash no están implementadas. - poschel

la desigualdad de la diferencia. ¡Pensamiento bastante extraño! Me encanta - nitinr708

a menos que tu cadena sea 'foo' sin embargo - veneno

Yo mismo escribí esta misma solución (porque mi intérprete no aceptaba las respuestas principales) y luego busqué una mejor, ¡pero encontré esta! - BuvinJ

no parece funcionar para mí: ejecutando Ubuntu Mate 20.04, $XDG_CURRENT_DESKTOP contiene MATE, y corriendo: if [ "$XDG_CURRENT_DESKTOP" != "${string/GNOME/}" ]; then echo MATCHES GNOME fi imprime COINCIDE CON GNOME ... piensa que "MATE" coincide con "GNOME" ... ¿dafuq? - Hanshenrik

Entonces, hay muchas soluciones útiles para la pregunta, pero ¿cuál es la más rápida / utiliza la menor cantidad de recursos?

Pruebas repetidas usando este marco:

/usr/bin/time bash -c 'a=two;b=onetwothree; x=100000; while [ $x -gt 0 ]; do TEST ; x=$(($x-1)); done'

Reemplazo de TEST cada vez:

[[ $b =~ $a ]]           2.92 user 0.06 system 0:02.99 elapsed 99% CPU

[ "${b/$a//}" = "$b" ]   3.16 user 0.07 system 0:03.25 elapsed 99% CPU

[[ $b == *$a* ]]         1.85 user 0.04 system 0:01.90 elapsed 99% CPU

case $b in *$a):;;esac   1.80 user 0.02 system 0:01.83 elapsed 99% CPU

doContain $a $b          4.27 user 0.11 system 0:04.41 elapsed 99%CPU

(doContain estaba en la respuesta de F. Houri)

Y para las risitas:

echo $b|grep -q $a       12.68 user 30.86 system 3:42.40 elapsed 19% CPU !ouch!

Por lo tanto, la opción de sustitución simple gana como era de esperar, ya sea en una prueba extendida o en un caso. El estuche es portátil.

¡Salir a 100000 greps es predeciblemente doloroso! La vieja regla sobre el uso de servicios públicos externos sin necesidad es válida.

Respondido el 01 de enero de 20 a las 14:01

Buen punto de referencia. Me convenció de usar [[ $b == *$a* ]]. - Físico loco

Si estoy leyendo esto correctamente, case gana con el menor consumo de tiempo total. Falta un asterisco después $b in *$a aunque. Obtengo resultados un poco más rápidos para [[ $b == *$a* ]] que para case con el error corregido, pero también podría depender de otros factores, por supuesto. - triples

ideone.com/5roEVt tiene mi experimento con algunos errores adicionales corregidos y pruebas para un escenario diferente (donde la cadena en realidad no está presente en la cadena más larga). Los resultados son muy similares; [[ $b == *$a* ]] es rápido y case es casi tan rápido (y agradablemente compatible con POSIX). - triples

La expresión condicional [[ $b == *$a* ]] y la declaración del caso case $b in *$a):;;esac no son equivalentes en una condición de no coincidencia. Intercambiando $a y $b da como resultado el código de salida 1 para la expresión condicional [[ y salga el código 0 para case declaración. Según help case: Estado de salida: Devuelve el estado del último comando ejecutado. El estado de devolución es cero si sin patrón coincide, que probablemente no sea el comportamiento esperado. Para devolver 1 en la condición de no coincidencia, debe ser: case $b in *$a*):;; *) false ;; esac - ra

Esto también funciona:

if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  printf "Found needle in haystack"
fi

Y la prueba negativa es:

if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  echo "Did not find needle in haystack"
fi

Supongo que este estilo es un poco más clásico, menos dependiente de las características del shell Bash.

El -- El argumento es pura paranoia POSIX, que se usa para protegerse contra cadenas de entrada similares a opciones, como --abc or -a.

Nota: En un bucle cerrado, este código será mucho más más lento que el uso de funciones internas de Bash, ya que uno (o dos) procesos separados se crearán y conectarán a través de tuberías.

Respondido el 12 de junio de 15 a las 00:06

... pero el OP no dice cuál versión de bash; Por ejemplo, los bash más antiguos (como los que tiene solaris con frecuencia) pueden no incluir estas características de bash más nuevas. (Me he encontrado con este problema exacto (la coincidencia de patrones de bash no está implementada) en solaris con bash 2.0) - michael

echo es intransitable, deberías usar printf '%s' "$haystack en lugar de. - nyuszika7h

No, solo evita echo en conjunto para cualquier cosa que no sea texto literal sin escapes que no comience con un -. Puede funcionar para usted, pero no es portátil. Incluso bash's echo se comportará de manera diferente dependiendo de si el xpg_echo La opción está configurada. PD: Olvidé cerrar la comilla doble en mi comentario anterior. - nyuszika7h

@kevinarpe no estoy seguro, -- no aparece en el Especificaciones POSIX para printf, pero deberías usar printf '%s' "$anything" de todos modos, para evitar problemas si $anything contiene una % personaje. - nyuszika7h

@kevinarpe Basado en eso, probablemente lo sea. - nyuszika7h

Bash 4+ ejemplos. Nota: no usar comillas causará problemas cuando las palabras contengan espacios, etc. Siempre cite en Bash, IMO.

Aquí hay algunos ejemplos de Bash 4+:

Ejemplo 1, busque 'sí' en la cadena (no distingue entre mayúsculas y minúsculas):

    if [[ "${str,,}" == *"yes"* ]] ;then

Ejemplo 2, busque 'sí' en la cadena (no distingue entre mayúsculas y minúsculas):

    if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

Ejemplo 3, verifique 'sí' en la cadena (distingue entre mayúsculas y minúsculas):

     if [[ "${str}" == *"yes"* ]] ;then

Ejemplo 4, verifique 'sí' en la cadena (distingue entre mayúsculas y minúsculas):

     if [[ "${str}" =~ "yes" ]] ;then

Ejemplo 5, coincidencia exacta (distingue entre mayúsculas y minúsculas):

     if [[ "${str}" == "yes" ]] ;then

Ejemplo 6, coincidencia exacta (no distingue entre mayúsculas y minúsculas):

     if [[ "${str,,}" == "yes" ]] ;then

Ejemplo 7, coincidencia exacta:

     if [ "$a" = "$b" ] ;then

Ejemplo 8, comodín coincide con .ext (no distingue entre mayúsculas y minúsculas):

     if echo "$a" | egrep -iq "\.(mp[3-4]|txt|css|jpg|png)" ; then

¡A disfrutar!

Respondido el 01 de enero de 20 a las 14:01

Aaaah - Solo lo entendí después de descubrir que las dos comas en ${str,,} convertir $str a minúsculas. ¡Grandes soluciones / gran lista! - hey

As Paul mencionó en su comparación de desempeño:

if echo "abcdefg" | grep -q "bcdef"; then
    echo "String contains is true."
else
    echo "String contains is not true."
fi

Esto es compatible con POSIX como el 'caso "$ string" en' la respuesta proporcionada por Marcus, pero es un poco más fácil de leer que la respuesta del enunciado del caso. También tenga en cuenta que esto será mucho más lento que usar una declaración de caso. Como señaló Paul, no lo use en un bucle.

Respondido el 01 de enero de 20 a las 14:01

Qué tal esto:

text="   <tag>bmnmn</tag>  "
if [[ "$text" =~ "<tag>" ]]; then
   echo "matched"
else
   echo "not matched"
fi

Respondido el 15 de diciembre de 14 a las 16:12

= ~ es para la coincidencia de expresiones regulares, por lo tanto, es demasiado poderoso para el propósito del OP. - usuario49586

Esta respuesta de Stack Overflow fue el único que atrapó el espacio y el guión de los personajes:

# For null cmd arguments checking   
to_check=' -t'
space_n_dash_chars=' -'
[[ $to_check == *"$space_n_dash_chars"* ]] && echo found

Respondido el 01 de enero de 20 a las 13:01

Es una respuesta a esta misma pregunta. - Pedro Mortensen

[[ $string == *foo* ]] && echo "It's there" || echo "Couldn't find"

Respondido 28 Abr '15, 20:04

Agregaré que el echo "Couldn't find La declaración al final es un buen truco para devolver 0 estados de salida para estos comandos coincidentes. - nicodjimenez

@nicodjimenez ya no puede apuntar al estado de salida con esta solución. El estado de salida es absorbido por los mensajes de estado ... - Yahid

Eso es exactamente lo que quise decir ... si no tienes || echo "Couldn't find" luego devolverá un estado de salida de error si no hay ninguna coincidencia, lo que quizás no desee si está ejecutando una canalización de CI, por ejemplo, donde desea que todos los comandos devuelvan estados de salida sin error - nicodjimenez

Uno es:

[ $(expr $mystring : ".*${search}.*") -ne 0 ] && echo 'yes' ||  echo 'no'

Respondido 13 Feb 16, 17:02

expr es una de esas utilidades de navaja suiza que generalmente puede hacer lo que sea que necesite hacer, una vez que descubra cómo hacerlo, pero una vez implementado, nunca puede recordar por qué o cómo está haciendo lo que está haciendo, por lo que no vuelva a tocarlo nunca, y espere que nunca deje de hacer lo que está haciendo. - michael

@AloisMahdal Nunca voté en contra, solo estoy postulando por qué se dieron los votos en contra. Un comentario de advertencia. Yo uso expr, en raras ocasiones, cuando la portabilidad impide el uso de bash (por ejemplo, comportamiento inconsistente en versiones anteriores), tr (inconsistente en todas partes) o sed (a veces demasiado lento). Pero por experiencia personal, cada vez que relee estos expr-ismas, tengo que volver a la página de manual. Entonces, solo comentaría que cada uso de expr ser comentado ... - michael

Hubo un tiempo en el que todo lo que tenías era el caparazón de Bourne original. Carecía de algunas características comúnmente requeridas, por lo que herramientas como expr y test fueron implementados para realizarlos. En esta época, generalmente hay mejores herramientas, muchas de ellas integradas en cualquier caparazón moderno. supongo test todavía está ahí, pero nadie parece faltar expr. - triples

My .bash_perfil file y cómo usé grep:

Si la variable de entorno PATH incluye mis dos bin directorios, no los anexes,

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

U=~/.local.bin:~/bin

if ! echo "$PATH" | grep -q "home"; then
    export PATH=$PATH:${U}
fi

Respondido el 01 de enero de 20 a las 14:01

¿Es esta una respuesta? - códigoforester

voto a favor. ¿Por qué molestarse en aprender cómo lo hace Bash cuando es más que probable que grep, mucho más poderoso, esté disponible? también extiéndalo un poco más al compararlo con una lista de patrones: grep -q -E 'pattern1|...|patternN'. - mohamed bana

grep -q es útil para este propósito.

El mismo uso awk:

string="unix-bash 2389"
character="@"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

Salida:

Extraviado

string="unix-bash 2389"
character="-"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

Salida:

Encontrado

Fuente original: http://unstableme.blogspot.com/2008/06/bash-search-letter-in-string-awk.html

respondido 28 mar '15, 16:03

echo es intransitable, deberías usar printf '%s' "$string" en lugar de. Estoy editando la respuesta porque el usuario ya no parece existir. - nyuszika7h

De que manera es echo no portátil, @ nyuszika7h? - starbeamrainbowlabs

Me gusta sed.

substr="foo"
nonsub="$(echo "$string" | sed "s/$substr//")"
hassub=0 ; [ "$string" != "$nonsub" ] && hassub=1

Editar, lógica:

  • Use sed para eliminar la instancia de subcadena de la cadena

  • Si la cadena nueva difiere de la cadena anterior, existe una subcadena

respondido 05 mar '16, 14:03

Por favor agregue alguna explicación. Impartir la lógica subyacente es más importante que solo dar el código, porque ayuda al OP y a otros lectores a solucionar este y otros problemas similares por sí mismos zulán

Descubrí que necesitaba esta funcionalidad con bastante frecuencia, así que estoy usando una función de shell casera en mi .bashrc como este, que me permite reutilizarlo tantas veces como sea necesario, con un nombre fácil de recordar:

function stringinstring()
{
    case "$2" in
       *"$1"*)
          return 0
       ;;
    esac
    return 1
}

Para probar si $string1 (decir, abecedario) está contenido en $string2 (decir, 123abcABC) Solo necesito correr stringinstring "$string1" "$string2" y compruebe el valor de retorno, por ejemplo

stringinstring "$str1" "$str2"  &&  echo YES  ||  echo NO

Respondido el 01 de enero de 20 a las 13:01

[["$ str" == $ substr ]] && echo SÍ || echo NO - elyase

Estoy bastante seguro de que el x hack solo es necesario para conchas viejas. - nyuszika7h

El nombre adecuado, e inmediatamente reconocible, para su función sería strstr() :-)- mijail t

@MikhailT .: siéntete libre de manejar esto como quieras ... :-) - Kurt Pfeifle

Ampliación de la pregunta respondida aquí ¿Cómo se sabe si una cadena contiene otra cadena en POSIX sh?:

Esta solución funciona con caracteres especiales:

# contains(string, substring)
#
# Returns 0 if the specified string contains the specified substring,
# otherwise returns 1.
contains() {
    string="$1"
    substring="$2"

    if echo "$string" | $(type -p ggrep grep | head -1) -F -- "$substring" >/dev/null; then
        return 0    # $substring is in $string
    else
        return 1    # $substring is not in $string
    fi
}

contains "abcd" "e" || echo "abcd does not contain e"
contains "abcd" "ab" && echo "abcd contains ab"
contains "abcd" "bc" && echo "abcd contains bc"
contains "abcd" "cd" && echo "abcd contains cd"
contains "abcd" "abcd" && echo "abcd contains abcd"
contains "" "" && echo "empty string contains empty string"
contains "a" "" && echo "a contains empty string"
contains "" "a" || echo "empty string does not contain a"
contains "abcd efgh" "cd ef" && echo "abcd efgh contains cd ef"
contains "abcd efgh" " " && echo "abcd efgh contains a space"

contains "abcd [efg] hij" "[efg]" && echo "abcd [efg] hij contains [efg]"
contains "abcd [efg] hij" "[effg]" || echo "abcd [efg] hij does not contain [effg]"

contains "abcd *efg* hij" "*efg*" && echo "abcd *efg* hij contains *efg*"
contains "abcd *efg* hij" "d *efg* h" && echo "abcd *efg* hij contains d *efg* h"
contains "abcd *efg* hij" "*effg*" || echo "abcd *efg* hij does not contain *effg*"

Respondido el 01 de enero de 20 a las 14:01

La prueba contains "-n" "n" no funciona aquí, porque echo -n se tragará el -n ¡como una opción! Una solución popular para eso es usar printf "%s\n" "$string" en lugar de. - joeytwiddle

Puesto que el POSIX/ La pregunta de BusyBox está cerrada sin proporcionar la respuesta correcta (en mi humilde opinión), publicaré una respuesta aquí.

La respuesta más corta posible es:

[ ${_string_##*$_substring_*} ] || echo Substring found!

or

[ "${_string_##*$_substring_*}" ] || echo 'Substring found!'

Tenga en cuenta que doble hash is obligatorio con unas conchasash). Arriba evaluará [ stringvalue ] cuando no se encuentra la subcadena. No devuelve ningún error. Cuando se encuentra la subcadena, el resultado está vacío y se evalúa [ ]. Esto arrojará el código de error 1 ya que la cadena está completamente sustituida (debido a *).

La sintaxis más corta más común:

[ -z "${_string_##*$_substring_*}" ] && echo 'Substring found!'

or

[ -n "${_string_##*$_substring_*}" ] || echo 'Substring found!'

Otro:

[ "${_string_##$_substring_}" != "$_string_" ] && echo 'Substring found!'

or

[ "${_string_##$_substring_}" = "$_string_" ] || echo 'Substring found!'

Nota la soltero ¡signo igual!

Respondido el 01 de enero de 20 a las 14:01

Coincidencia exacta de palabras:

string='My long string'
exactSearch='long'

if grep -E -q "\b${exactSearch}\b" <<<${string} >/dev/null 2>&1
  then
    echo "It's there"
  fi

respondido 10 nov., 16:14

Prueba oobash.

Es una biblioteca de cadenas de estilo OO para Bash 4. Tiene soporte para diéresis alemanas. Está escrito en Bash.

Hay muchas funciones disponibles: -base64Decode, -base64Encode, -capitalize, -center, -charAt, -concat, -contains, -count, -endsWith, -equals, -equalsIgnoreCase, -reverse, -hashCode, -indexOf, -isAlnum, -isAlpha, -isAscii, -isDigit, -isEmpty, -isHexDigit, -isLowerCase, -isSpace, -isPrintable, -isUpperCase, -isVisible, -lastIndexOf, -length, -matches, -replaceAll, -replaceFirst, -startsWith, -substring, -swapCase, -toLowerCase, -toString, -toUpperCase, -trim y -zfill.

Mira el contiene ejemplo:

[Desktop]$ String a testXccc
[Desktop]$ a.contains tX
true
[Desktop]$ a.contains XtX
false

oobash está disponible en Sourceforge.net.

Respondido el 01 de enero de 20 a las 13:01

case $string in (*foo*)
  # Do stuff
esac

Esta es la misma respuesta que https://stackoverflow.com/a/229585/11267590. Pero estilo simple y también compatible con POSIX.

respondido 27 mar '20, 10:03

Utilizo esta función (una dependencia no incluida pero obvia). Pasa las pruebas que se muestran a continuación. Si la función devuelve un valor> 0, entonces se encontró la cadena. En su lugar, podría devolver fácilmente 1 o 0.

function str_instr {
   # Return position of ```str``` within ```string```.
   # >>> str_instr "str" "string"
   # str: String to search for.
   # string: String to search.
   typeset str string x
   # Behavior here is not the same in bash vs ksh unless we escape special characters.
   str="$(str_escape_special_characters "${1}")"
   string="${2}"
   x="${string%%$str*}"
   if [[ "${x}" != "${string}" ]]; then
      echo "${#x} + 1" | bc -l
   else
      echo 0
   fi
}

function test_str_instr {
   str_instr "(" "'foo@host (dev,web)'" | assert_eq 11
   str_instr ")" "'foo@host (dev,web)'" | assert_eq 19
   str_instr "[" "'foo@host [dev,web]'" | assert_eq 11
   str_instr "]" "'foo@host [dev,web]'" | assert_eq 19
   str_instr "a" "abc" | assert_eq 1
   str_instr "z" "abc" | assert_eq 0
   str_instr "Eggs" "Green Eggs And Ham" | assert_eq 7
   str_instr "a" "" | assert_eq 0
   str_instr "" "" | assert_eq 0
   str_instr " " "Green Eggs" | assert_eq 6
   str_instr " " " Green "  | assert_eq 1
}

Respondido 11 Abr '18, 03:04

¡El suspenso! Qué is la dependencia? - Pedro Mortensen

La función "str_escape_special_characters". Está en el archivo arcshell_str.sh de GitHub. arcshell.io te llevará allí. - Ethan Publicar

str_escape_special_characters parece haberse convertido str_escape. ver arcshell_str.sh @ arclogicsoftware / arcshell - pkfm

El genérico pajar de agujas El ejemplo sigue con las variables

#!/bin/bash

needle="a_needle"
haystack="a_needle another_needle a_third_needle"
if [[ $haystack == *"$needle"* ]]; then
    echo "needle found"
else
    echo "needle NOT found"
fi

respondido 17 mar '20, 10:03

msg="message"

function check {
    echo $msg | egrep [abc] 1> /dev/null

    if [ $? -ne 1 ];
    then 
        echo "found" 
    else 
        echo "not found" 
    fi
}

check

Esto encontrará cualquier ocurrencia de a o b o c

Respondido 13 Feb 20, 00:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.