La siguiente sintaxis bash verifica si param
no está vacía:
[[ ! -z $param ]]
Por ejemplo:
param=""
[[ ! -z $param ]] && echo "I am not zero"
No hay salida y está bien.
Pero cuando param
está 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
-z
prueba 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
param
variable 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 depattern
constring
. Cuandopattern
comienza con/
(como arriba), reemplaza todos los partidos. Como el reemplazo está vacío, podemos omitir el final/
y elstring
valor:Después de todo eso, terminamos con
${param// }
eliminar todos los espacios.Tenga en cuenta que aunque está presente en
ksh
(donde se originó),zsh
ybash
, esa sintaxis no es POSIX y no debe usarse ensh
scripts.fuente
sed
dijeron ... soloecho
la 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 quepattern
está vacía yreplacement string
es un espacio único. AH! Ahora lo veo,if pattern begins with a slash
me 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 lacase
construcció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*)
case
un 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
zsh
parece tener problemas con[![:blank:]]
, elevar:b
es modificador no válido. Ensh
yksh
emular, 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.:b
modificador inválido es un poco extraño.sh
estábash
construido con--enable-xpg-echo-default
y--enable-strict-posix-default
para 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/sh
es 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
printf
construcción en sí es muy portátil, pero confiar en ella es mucho menos molesta que descubrir qué varianteecho
tiene).fuente
case
.case
globo para detectar una cadena que está vacía o que contiene solo caracteres de espacio en blanco. (Sería fácil con unacase
expresió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 losIFS
caracteres, puede usar el patrón*[$IFS]*
.<space><tab><newline>
al principio y luego nunca toca de nuevo. Pensé que sería una distracción..profile
que ha sido ejecutado por muchos proyectiles Bourne. Por supuesto[$IFS]
, no hará lo que se pretendía siIFS
tiene 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=aaaa
luego 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$name
valor no nulo o matará al shell. Entonces, por la misma razón que usted no hace,prompt > $randomvar
tampoco 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