scripts script resueltos paso pasar parametros manejo hacer español ejercicios ejemplos como comandos cadenas string bash comparison

string - paso - scripts linux ejercicios resueltos



En bash, ¿cómo puedo verificar si una cadena comienza con algún valor? (11)

@OP, para tus dos preguntas puedes usar case / esac

string="node001" case "$string" in node*) echo "found";; * ) echo "no node";; esac

segunda pregunta

case "$HOST" in node*) echo "ok";; user) echo "ok";; esac case "$HOST" in node*|user) echo "ok";; esac

O Bash 4.0

case "$HOST" in user) ;& node*) echo "ok";; esac

Me gustaría comprobar si una cadena comienza con "node", por ejemplo, "node001". Algo como

if [ $HOST == user* ] then echo yes fi

¿Cómo puedo hacerlo correctamente?

Además, necesito combinar expresiones para comprobar si HOST es "usuario1" o comienza con "nodo"

if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ]; then echo yes fi > > > -bash: [: too many arguments

¿Cómo hacerlo correctamente?


Agregando un poco más de detalle de sintaxis a la respuesta de rango más alto de Mark Rushakoff.

La expresion

$HOST == node*

También se puede escribir como

$HOST == "node"*

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).


Este fragmento de la Guía avanzada de scripts de Bash dice:

# The == comparison operator behaves differently within a double-brackets # test than within single brackets. [[ $a == z* ]] # True if $a starts with a "z" (wildcard matching). [[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

Así que lo tenías casi correcto; necesitabas corchetes dobles , no corchetes simples.

Con respecto a tu segunda pregunta, puedes escribirla de esta manera:

HOST=user1 if [[ $HOST == user1 ]] || [[ $HOST == node* ]] ; then echo yes1 fi HOST=node001 if [[ $HOST == user1 ]] || [[ $HOST == node* ]] ; then echo yes2 fi

Que hará eco

yes1 yes2

Bash es if es difícil acostumbrarse a la sintaxis (IMO).


Otra cosa que puede hacer es descartar lo que está haciendo eco y canalizar con inline cut -c 1-1


Prefiero los otros métodos ya publicados, pero a algunas personas les gusta usar:

case "$HOST" in user1|node*) echo "yes";; *) echo "no";; esac

Editar:

He agregado sus alternativas a la declaración del caso anterior

En tu versión editada tienes demasiados paréntesis. Debe tener un aspecto como este:

if [[ $HOST == user1 || $HOST == node* ]];


Puede seleccionar solo la parte de la cadena que desea verificar:

if [ ${HOST:0:4} = user ]

Para su pregunta de seguimiento, puede utilizar un OR :

if [[ $HOST == user1 || $HOST == node* ]]


Si bien aquí la mayoría de las respuestas son bastante correctas, muchas de ellas contienen bashismos innecesarios. La expansión de parámetros POSIX le ofrece todo lo que necesita:

[ "${host#user}" != "${host}" ]

y

[ "${host#node}" != "${host}" ]

${var#expr} elimina el prefijo más pequeño que coincide con expr de ${var} y lo devuelve. Por lo tanto, si ${host} no comienza con el user ( node ), ${host#user} ( ${host#node} ) es lo mismo que ${host} .

expr permite fnmatch() comodines, por lo que ${host#node??} y amigos también funcionan.


Si está utilizando un reciente bash (v3 +), sugiera el operador de comparación bash regex =~ , es decir,

if [[ "$HOST" =~ ^user.* ]]; then echo "yes" fi

Para igualar this or that en una expresión regular use | es decir

if [[ "$HOST" =~ ^user.*|^host1 ]]; then echo "yes" fi

Nota: esta es la sintaxis de expresión regular "correcta".

  • user* significa use y cero o más apariciones de r , por lo que use y userrrr coincidirán.
  • user.* significa user y cero o más ocurrencias de cualquier carácter, por lo que userX , userX coincidirá.
  • ^user.* significa que coincida con el patrón de user.* al comienzo de $ HOST.

Si no está familiarizado con la sintaxis de expresiones regulares, intente consultar este recurso .

Nota: es mejor si hace cada nueva pregunta como una nueva pregunta, hace que sea más ordenado y más útil. Siempre puede incluir un enlace a una pregunta anterior como referencia.


Siempre trato de mantener POSIX sh en lugar de usar las extensiones de bash, ya que uno de los puntos principales de las secuencias de comandos es la portabilidad. (Además de conectar programas, no reemplazarlos)

En sh, hay una manera fácil de verificar una condición "es-prefijo".

case $HOST in node*) your code here esac

Teniendo en cuenta la antigüedad, arcano y crufty sh (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 el case están integrados en, las construcciones resultantes no son diferentes a cualquier otro trabajo. Se pueden componer de la misma manera:

if case $HOST in node*) true;; *) false;; esac; then your code here fi

O incluso más corto

if case $HOST in node*) ;; *) false;; esac; then your code here fi

O incluso más corto (solo para presentar ! Como elemento del idioma, pero ahora es un estilo malo)

if ! case $HOST in node*) false;; esac; then your code here fi

Si te gusta ser explícito, crea tu propio elemento de idioma:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; }

¿No es esto realmente agradable?

if beginswith node "$HOST"; then your code here fi

Y dado que sh es básicamente solo trabajos y listas de cadenas (y procesos internos, de los cuales se componen los trabajos), ahora podemos hacer algo de programación funcional ligera:

beginswith() { case $2 in "$1"*) true;; *) false;; esac; } checkresult() { if [ $? = 0 ]; then echo TRUE; else echo FALSE; fi; } all() { test=$1; shift for i in "$@"; do $test "$i" || return done } all "beginswith x" x xy xyz ; checkresult # prints TRUE all "beginswith x" x xy abc ; checkresult # prints FALSE

Esto es elegante No es que abogue por usar sh para nada serio, se rompe demasiado rápido en los requisitos del mundo real (no lambdas, por lo que debe usar cadenas. Pero no es posible realizar llamadas de función de anidación con cadenas, no es posible usar tuberías ...)


ya que # tiene un significado en bash llegué a la siguiente solución.
Además, me gusta más empaquetar cuerdas con "" para superar espacios, etc.

A="#sdfs" if [[ "$A" == "#"* ]];then echo "skip comment line" fi


if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ]; then echo yes fi

no funciona, porque todos [ , [[ y la prueba reconocen la misma gramática no recurrente. Consulte la sección EXPRESIONES CONDICIONALES en su página de manual de bash.

Como un aparte, el SUSv3 dice

El comando condicional derivado de KornShell (doble corchete [[]] ) se eliminó de la descripción del lenguaje del comando de shell en una propuesta inicial. Se plantearon objeciones de que el problema real es el uso incorrecto del comando de prueba ( [ ), y ponerlo en el shell es la forma incorrecta de solucionar el problema. En su lugar, la documentación adecuada y una nueva palabra de shell reservada ( ! ) Son suficientes.

Las pruebas que requieren múltiples operaciones de prueba se pueden realizar a nivel de shell utilizando invocaciones individuales del comando de prueba y las lógicas de shell, en lugar de usar el indicador de prueba propenso a errores.

necesitarías escribirlo de esta manera, pero la prueba no lo admite:

if [ $HOST == user1 -o $HOST == node* ]; then echo yes fi

prueba usa = para la igualdad de cadenas, lo más importante es que no admite la coincidencia de patrones.

case / esac tiene un buen soporte para la coincidencia de patrones:

case $HOST in user1|node*) echo yes ;; esac

tiene el beneficio adicional de que no depende de bash, la sintaxis es portátil. de la Especificación Unix única, el lenguaje de comandos de shell:

case word in [(]pattern1) compound-list;; [[(]pattern[ | pattern] ... ) compound-list;;] ... [[(]pattern[ | pattern] ... ) compound-list] esac