Pregunta

Necesito comparar cadenas en shell:

var1="mtu eth0"

if [ "$var1" == "mtu *" ]
then
    # do something
fi

Pero obviamente el " * " No funciona en Shell. ¿Hay alguna manera de hacerlo?

¿Fue útil?

Solución

bash

Solución más corta:

if [[ "$var1" = "mtu "* ]]

El [[]] de Bash no se expande globalmente, a diferencia de [] (que debe, por razones históricas).


bash --posix

Oh, publiqué demasiado rápido. Bourne shell, no Bash ...

if [ "${var1:0:4}" == "mtu " ]

$ {var1: 0: 4} significa los primeros cuatro caracteres de $ var1 .


/bin/sh

Ah, lo siento. La emulación POSIX de Bash no va lo suficientemente lejos; un verdadero Bourne shell original no tiene $ {var1: 0: 4} . Necesitarás algo como la solución de mstrobl.

if [ "$(echo "$var1" | cut -c0-4)" == "mtu " ]

Otros consejos

Usa las herramientas de Unix. El programa cut acortará felizmente una cadena.

if [ "$(echo $var1 | cut -c 4)" = "mtu " ];

... deberías hacer lo que quieras.

Puede llamar a expr para hacer coincidir cadenas con expresiones regulares dentro de los scripts de Bourne Shell. Lo siguiente parece funcionar:

#!/bin/sh

var1="mtu eth0"

if [ "`expr \"$var1\" : \"mtu .*\"`" != "0" ];then
  echo "match"
fi

Yo haría lo siguiente:

# Removes anything but first word from "var1"
if [ "${var1%% *}" = "mtu" ] ; then ... fi

O:

# Tries to remove the first word if it is "mtu", checks if we removed anything
if [ "${var1#mtu }" != "$var1" ] ; then ... fi

En el shell Bourne, si quiero verificar si una cadena contiene otra cadena:

if [  `echo ${String} | grep -c ${Substr} ` -eq 1 ] ; then

Adjuntar echo $ {String} | grep -c $ {Substr} con dos backticks `:

Para verificar si la subcadena está al principio o al final:

if [ `echo ${String} | grep -c "^${Substr}"` -eq 1 ] ; then
...
if [ `echo ${String} | grep -c "${Substr}<*>quot;` -eq 1 ] ; then

Me gusta usar la declaración de caso para comparar cadenas.

Un ejemplo trivial es

case "$input"
in
  "$variable1") echo "matched the first value" 
     ;;
  "$variable2") echo "matched the second value"
     ;;
  *[a-z]*)  echo "input has letters" 
     ;;
  '')       echo "input is null!"
     ;;
   *[0-9]*)  echo "matched numbers (but I don't have letters, otherwise the letter test would have been hit first!)"
     ;;
   *) echo "Some wacky stuff in the input!"
esac

He hecho locuras como

case "$(cat file)"
in
  "$(cat other_file)")  echo "file and other_file are the same"
      ;;
  *)  echo "file and other_file are different"
esac

Y eso también funciona, con algunas limitaciones, como que los archivos no pueden tener más de un par de megabytes y el shell simplemente no ve nulos, por lo que si un archivo está lleno de nulos y el otro no tiene ninguno, ( y tampoco tienen nada más), esta prueba no verá ninguna diferencia entre los dos.

No uso la comparación de archivos como un ejemplo serio, solo un ejemplo de cómo la declaración de caso es capaz de hacer una coincidencia de cadenas mucho más flexible que la que está disponible con test o expr u otras expresiones de shell similares.

O, como ejemplo del operador = ~ :

if [[ "$var1" =~ "mtu *" ]]
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top