Me gustaría comprobar si una cadena comienza con "nodo", por ejemplo, "nodo001". Algo como
if [ $HOST == user* ]
then
echo yes
fi
¿Cómo puedo hacerlo correctamente?
Además, necesito combinar expresiones para verificar si HOST es "user1" o comienza con "node"
if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi
> > > -bash: [: too many arguments
¿Cómo puedo hacerlo correctamente?
string
bash
comparison
Tim
fuente
fuente
Respuestas:
Este fragmento de la Guía avanzada de secuencias de comandos Bash dice:
Entonces lo tenías casi correcto; necesitabas corchetes dobles , no corchetes individuales.
Con respecto a su segunda pregunta, puede escribirla de esta manera:
Que hará eco
if
Es difícil acostumbrarse a la sintaxis de Bash (IMO).fuente
[[ $a == z* ]]
y[[ $a == "z*" ]]
? En otras palabras: ¿funcionan de manera diferente? ¿Y a qué te refieres específicamente cuando dices "$ a es igual a z *"?[[ $a == *com ]]
Si está utilizando una versión reciente de Bash (v3 +), sugiero el operador de comparación de expresiones regulares de Bash
=~
, por ejemplo,Para coincidir
this or that
en una expresión regular, use|
, por ejemplo,Nota: esta es la sintaxis de expresión regular 'adecuada'.
user*
significause
y cero o más ocurrencias der
, entoncesuse
yuserrrr
coincidirá.user.*
significauser
y cero o más ocurrencias de cualquier carácter, por lo tantouser1
,userX
coincidirán.^user.*
significa hacer coincidir el patrónuser.*
al comienzo de $ HOST.Si no está familiarizado con la sintaxis de expresiones regulares, intente consultar este recurso .
fuente
=~
operador Bash solo hace coincidencia de expresiones regulares cuando el lado derecho está sin comillas. Si cita el lado derecho "Cualquier parte del patrón puede ser citada para forzar que coincida como una cadena". (1.) asegúrese de poner siempre las expresiones regulares a la derecha sin comillas y (2.) si almacena su expresión regular en una variable, asegúrese de NO citar el lado derecho cuando realice la expansión de parámetros.Siempre trato de mantener POSIX en
sh
lugar de usar extensiones Bash, ya que uno de los puntos principales de la secuencia de comandos es la portabilidad (además de conectar programas, no reemplazarlos).En
sh
, hay una manera fácil de verificar si hay una condición "es-prefijo".Dada la antigüedad, sh arcano y crujiente (y Bash no es la cura: es más complicado, menos consistente y menos portátil), me gustaría señalar un aspecto funcional muy agradable: mientras que algunos elementos de sintaxis como
case
están incorporados , las construcciones resultantes no son diferentes a cualquier otro trabajo. Se pueden componer de la misma manera:O incluso más corto
O incluso más corto (solo para presentarlo
!
como un elemento del lenguaje, pero este es un mal estilo ahora)Si te gusta ser explícito, crea tu propio elemento de lenguaje:
¿No es esto realmente bastante agradable?
Y dado
sh
que básicamente son solo trabajos y listas de cadenas (y procesos internos, de los cuales se componen los trabajos), ahora podemos incluso hacer una programación funcional ligera:Esto es elegante No es que yo recomendaría usar
sh
algo serio: se rompe demasiado rápido según los requisitos del mundo real (no hay lambdas, por lo que debemos usar cadenas. Pero anidar llamadas de función con cadenas no es posible, las tuberías no son posibles, etc.)fuente
case $HOST in user01 | node* ) ...
if case $HOST in node*) true;; *) false;; esac; then
Lo he visto aquí y allá, a mi parecer, parece un poco arrugado.case
comandos se convierten en comandos, pueden entrarif ... then
.beginswith() { case "$2" in "$1"*) true;; *) false;; esac; }
otra manera si$1
tiene un literal*
o?
podría dar una respuesta incorrecta.Puede seleccionar solo la parte de la cadena que desea verificar:
Para su pregunta de seguimiento, puede usar un OR :
fuente
${HOST:0:4}
HOST='a b'; if [ ${HOST:0:4} = user ] ; then echo YES ; fi
Prefiero los otros métodos ya publicados, pero a algunas personas les gusta usar:
Editar:
He agregado sus alternativas a la declaración de caso anterior
En su versión editada tiene demasiados corchetes. Debe tener un aspecto como este:
fuente
Si bien la mayoría de las respuestas aquí son bastante correctas, muchas de ellas contienen Bashismos innecesarios. La expansión de parámetros POSIX le brinda todo lo que necesita:
y
${var#expr}
tiras el más pequeño emparejamiento de prefijoexpr
de${var}
y rendimientos. Por tanto, si${host}
no no comenzar conuser
(node
),${host#user}
(${host#node}
) es el mismo que${host}
.expr
permitefnmatch()
comodines, por lo tanto${host#node??}
y amigos también funcionan.fuente
[[ $host == user* ]]
podría ser necesario, ya que es mucho más legible que[ "${host#user}" != "${host}" ]
. Como tal, dado que usted controla el entorno donde se ejecuta el script (apunte a las últimas versiones debash
), es preferible el primero.has_prefix()
función y nunca lo volvería a ver.Ya que
#
tiene un significado en Bash, llegué a la siguiente solución.Además, me gusta más empacar cadenas con "" para superar espacios, etc.
fuente
blah:
, ¡parece que esta es la respuesta!Agregando un poco más de detalle de sintaxis a la respuesta de rango más alto de Mark Rushakoff.
La expresion
También se puede escribir como
El efecto es el mismo. Solo asegúrese de que el comodín esté fuera del texto citado. Si el comodín está dentro de las comillas, se interpretará literalmente (es decir, no como un comodín).
fuente
@OP, para ambas preguntas puede usar case / esac:
Segunda pregunta
O Bash 4.0
fuente
;&
solo está disponible en Bash> = 4.no funciona, porque todos
[
,[[
ytest
reconocer la misma gramática recursiva. Consulte la sección EXPRESIONES CONDICIONALES en su página de manual de Bash.Como un aparte, el SUSv3 dice
Tendría que escribirlo de esta manera, pero la prueba no lo admite:
prueba utiliza = para la igualdad de cadena, y lo más importante, no admite la coincidencia de patrones.
case
/esac
tiene buen soporte para la coincidencia de patrones:Tiene el beneficio adicional de que no depende de Bash, y la sintaxis es portátil. De la especificación Single Unix , el lenguaje de comandos de Shell :
fuente
[
ytest
son Bash incorporados, así como programas externos. Tratartype -a [
.if [ -z $aa -or -z $bb ]
; ... da " bash: [: -or: operador binario esperado "; Sin embargoif [ -z "$aa" -o -z "$bb" ] ; ...
pasa.grep
Olvidando el rendimiento, esto es POSIX y se ve mejor que las
case
soluciones:Explicación:
printf '%s'
para evitar laprintf
expansión de las barras invertidas: Bash printf literal literal textgrep -q
evita el eco de coincidencias con stdout: Cómo verificar si un archivo contiene una cadena específica usando Bashgrep -E
habilita expresiones regulares extendidas, que necesitamos para^
fuente
Ajusté la respuesta de @ markrushakoff para que sea una función invocable:
Úselo así:
Aquí hay una versión más compleja que proporciona un valor predeterminado especificado:
Úselo así:
fuente
Otra cosa que puedes hacer es
cat
descubrir qué es lo que estás haciendo eco yinline cut -c 1-1
fuente