La siguiente sintaxis bash verifica si paramno está vacía:
[[ ! -z $param ]]
Por ejemplo:
param=""
[[ ! -z $param ]] && echo "I am not zero"
No hay salida y está bien.
Pero cuando paramestá vacío excepto por uno (o más) caracteres de espacio, entonces el caso es diferente:
param=" " # one space
[[ ! -z $param ]] && echo "I am not zero"
Se emite "No soy cero".
¿Cómo puedo cambiar la prueba para considerar variables que contienen solo caracteres de espacio como vacías?
bash
shell
shell-script
string
maihabunash
fuente
fuente

man test:-z STRING - the length of STRING is zero. Si desea eliminar todos los espacios$param, use${param// /}trim()función simple incorporada en cualquier * nix? Tantos[[ ! -z $param ]]es equivalente atest ! -z $param.Respuestas:
Primero, tenga en cuenta que la
-zprueba es explícitamente para:Es decir, una cadena que contiene solo espacios no debería ser verdadera debajo
-z, porque tiene una longitud distinta de cero.Lo que desea es eliminar los espacios de la variable utilizando la expansión del parámetro de reemplazo de patrón :
Esto expande la
paramvariable y reemplaza todas las coincidencias del patrón(un solo espacio) con nada, por lo que una cadena que solo tiene espacios se expandirá a una cadena vacía.Lo esencial de cómo funciona eso es que
${var/pattern/string}reemplaza la primera combinación más larga depatternconstring. Cuandopatterncomienza con/(como arriba), reemplaza todos los partidos. Como el reemplazo está vacío, podemos omitir el final/y elstringvalor:Después de todo eso, terminamos con
${param// }eliminar todos los espacios.Tenga en cuenta que aunque está presente en
ksh(donde se originó),zshybash, esa sintaxis no es POSIX y no debe usarse enshscripts.fuente
seddijeron ... soloechola variable que dijeron ...${var/pattern/string}así, ¿no debería ser[[ -z ${param/ /} ]]con el espacio entre las barras el patrón y nada más que la cadena?[[ -z "${param// }" ]]seguramente parece quepatternestá vacía yreplacement stringes un espacio único. AH! Ahora lo veo,if pattern begins with a slashme perdí esa parte. entonces el patrón es/y la cadena se deja y, por lo tanto, está vacía. Gracias.La manera fácil de verificar que una cadena solo contenga caracteres en un conjunto autorizado es probar la presencia de caracteres no autorizados. Por lo tanto, en lugar de probar si la cadena solo contiene espacios, pruebe si la cadena contiene algún carácter que no sea espacio. En bash, ksh o zsh:
“Consiste solo en espacios” incluye el caso de una variable vacía (o no establecida).
Es posible que desee probar cualquier carácter de espacio en blanco. Utilícelo
[[ $param = *[^[:space:]]* ]]para usar la configuración regional o cualquier lista explícita de caracteres de espacios en blanco que desee probar, por ejemplo,[[ $param = *[$' \t\n']* ]]para probar el espacio, la pestaña o la nueva línea.Hacer coincidir una cadena con un patrón con el
=interior[[ … ]]es una extensión ksh (también presente en bash y zsh). En cualquier estilo Bourne / POSIX, puede usar lacaseconstrucción para hacer coincidir una cadena con un patrón. Tenga en cuenta que los patrones de shell estándar se utilizan!para negar un conjunto de caracteres, en lugar de^como en la mayoría de las sintaxis de expresiones regulares.Para probar los caracteres de espacios en blanco, la
$'…'sintaxis es específica de ksh / bash / zsh; puede insertar estos caracteres en su script literalmente (tenga en cuenta que una nueva línea tendrá que estar entre comillas, ya que la barra invertida + nueva línea se expande a nada), o generarlos, por ejemplofuente
${var?not set}, pasar esa prueba y sobrevivir garantizaría que una variable coincidente con la suya tenga*)caseun efecto definitivo respuesta, por ejemplo.[[ $param = *[!\ ]* ]]enmksh.POSIXY:
Para diferenciar entre en blanco , no esté en blanco , vacío , unset :
[:blank:]es para los caracteres de espaciado horizontal (espacio y tabulación en ASCII, pero probablemente haya algunos más en su ubicación; algunos sistemas incluirán el espacio que no se rompe (donde esté disponible), otros no). Si también desea caracteres de espaciado vertical (como nueva línea o avance de formulario), reemplácelos[:blank:]por[:space:].fuente
zshparece tener problemas con[![:blank:]], elevar:bes modificador no válido. Enshykshemular, se[var=foo zsh -c 'case ${var+x$var} in (x*[![:blank:]]*) echo x; esac'esta bien para mi. El evento no encontrado solo sería para shells interactivos.:bmodificador inválido es un poco extraño.shestábashconstruido con--enable-xpg-echo-defaulty--enable-strict-posix-defaultpara ser compatible con Unix (lo que implicaecho '\t'generar una pestaña).La única razón restante para escribir un script de shell, en lugar de un script en un buen lenguaje de script, es si la portabilidad extrema es una preocupación primordial. El legado
/bin/shes lo único que puede estar seguro de que tiene, pero Perl, por ejemplo, es más probable que esté disponible multiplataforma que Bash. Por lo tanto, nunca escriba scripts de shell que utilicen funciones que no sean realmente universales , y tenga en cuenta que varios proveedores de Unix propietarios congelaron su entorno de shell antes de POSIX.1-2001 .Hay una forma portátil de hacer esta prueba, pero debe usar
tr:(El valor predeterminado de
$IFS, convenientemente, es un espacio, una pestaña y una nueva línea).(La
printfconstrucción en sí es muy portátil, pero confiar en ella es mucho menos molesta que descubrir qué varianteechotiene).fuente
case.caseglobo para detectar una cadena que está vacía o que contiene solo caracteres de espacio en blanco. (Sería fácil con unacaseexpresión regular , pero no hace expresiones regulares. La construcción en su respuesta no funcionará si le importan las nuevas líneas.)case $param in *[![:space:]]*) …. Si desea probar losIFScaracteres, puede usar el patrón*[$IFS]*.<space><tab><newline>al principio y luego nunca toca de nuevo. Pensé que sería una distracción..profileque ha sido ejecutado por muchos proyectiles Bourne. Por supuesto[$IFS], no hará lo que se pretendía siIFStiene ciertos valores no predeterminados (vacíos (o sin establecer), que contienen], comienzan con!o^).fuente
Para probar si la variable está vacía o contiene espacios, también puede usar este código:
fuente
:.name=aaaaluego ejecute este comandoecho ${name:?variable is empty}, imprimirá el valor del nombre de la variable y ahora ejecute este comandoecho ${name1:?variable is empty}, imprimirá -sh: nombre1: la variable está vacíaecho ${name:?variable is empty}evaluará el$namevalor no nulo o matará al shell. Entonces, por la misma razón que usted no hace,prompt > $randomvartampoco debería hacerlo${var?}: si hay un comando allí, probablemente se ejecutará, y no sabe qué es. Un shell interactivo no tiene que salir, por eso el tuyo no. Aún así, si desea ver algunas pruebas, hay muchas de ellas aquí. . Este no es tan largo ...Para probar si una variable no está definida, está vacía (tiene un valor nulo) o contiene solo espacios:
Explicación:
${param%%[! ]*}elimina desde el primer no espacio hasta el final.-z, entonces echoempty.Lo anterior es compatible con POSIX y se ejecuta en cualquier descendiente Bourne.
Si desea extender eso a las pestañas también, incluya una pestaña explícita:
o use una variable con los caracteres que necesita eliminar:
o puede usar alguna "expresión de clase de caracteres" POSIX (en blanco significa espacio y tabulación):
Pero eso fallará en mksh, lksh y posh.
fuente
Prueba esto:
fuente