2012-01-19 22 views
198

Supongo que no tengo claro cómo hacer las pruebas "y". Quería asegurarme de que existía un argumento que funcionaba bien con [ -e $VAR ], pero resulta que también se estaba evaluando como verdadero en una cadena vacía; que no quiero

¿Cómo 'y' ellos juntos? ¿O hay otra prueba única que logra lo que quiero?

Respuesta

361
if [ ! -z "$var" ] && [ -e "$var" ]; then 
     # something ... 
fi 
+7

Esta solución funciona incluso en conchas estrictamente POSIX y por lo tanto también en 'bash'; sin embargo, para aprovechar al máximo los "bashismos", consulte la respuesta de @paxdiablo. – mklement0

+1

Muy contento de ver esto aconsejado en lugar del obsoleto '-a'. –

+0

Encontré otra explicación excelente y detallada: http://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash – valentt

4
if [ -n "$var" -a -e "$var" ]; then 
    do something ... 
fi 

 

+9

Dado que 'POSIX' no define el comportamiento de '[' con conjuntos complejos de pruebas, debemos evitar el uso de '-a' o' -o' con '['. Lo leí [aquí] (http://mywiki.wooledge.org/BashGuide/TestsAndConditionals?highlight=%28conditional%29#Conditional_Blocks_.28if.2C_test_and_.5B.5B.29). –

+1

@ jaypal-singh Tienes razón, pero el tema tiene la etiqueta 'bash' y no mencionas acerca de POSIX, así que publico esta versión que funciona bajo' bash' y algunas otras conchas modernas. –

+2

Si está asumiendo el uso de 'bash' u otras conchas modernas, hay incluso * menos * razones para recomendar' -a'. – chepner

43

Desde la página de manual bash:

[[ expression ]] - devolverá un estado de 0 ó 1 dependiendo de la evaluación de la expresión expresión condicional.

Y, de manifestación, una de las opciones es:

expression1 && expression2 - cierto si tanto expression1 y expression2 son ciertas.

Para que pueda and juntos de la siguiente manera (-n es lo contrario de -z para que podamos deshacernos de la !):

if [[ -n "$var" && -e "$var" ]] ; then 
    echo "'$var' is non-empty and the file exists" 
fi 

Sin embargo, no creo que se necesita en este caso , -e xyzzy es verdadero si existe el archivo xyzzy y puede manejar bastante fácilmente las cadenas vacías. Si eso es lo que quieres, entonces en realidad no necesita el cheque -z no vacía:

pax> VAR=xyzzy 
pax> if [[ -e $VAR ]] ; then echo yes ; fi 
pax> VAR=/tmp 
pax> if [[ -e $VAR ]] ; then echo yes ; fi 
yes 

En otras palabras, sólo tiene que utilizar:

if [[ -e "$var" ]] ; then 
    echo "'$var' exists" 
fi 
+0

Podemos acortarlo con '[[-e "$ var"]] && echo " '$ var' existe"' –

+1

Sí, si se trata de una sola línea (como mi ejemplo fue). No haría eso si el bloque condicional fuera mucho más complejo. – paxdiablo

2

Basta citar la variable:

[ -e "$VAR" ] 

Esto evalúa a [ -e "" ] si $VAR está vacío.

Su versión no funciona porque evalúa a [ -e ]. Ahora, en este caso, bash simplemente comprueba si el único argumento (-e) es una cadena no vacía.

Desde la página de manual:

prueba y [evaluar expresiones condicionales mediante un conjunto de reglas basado en el número de argumentos. ...

1 argumento

La expresión es verdadera si y sólo si el argumento no es nulo.

(Además, esta solución tiene la ventaja adicional de trabajar con nombres de archivo que contiene espacios)

0

He encontrado una respuesta ahora, gracias por sus sugerencias!

for e in ./*.cutoff.txt; do 
if grep -q -E 'COX1|Cu-oxidase' $e 
then 
    echo xyz >$e.match.txt 
else 
    echo 
fi 

if grep -q -E 'AMO' $e 
then 
    echo abc >$e.match.txt 
else 
    echo 
fi; done 

¿Algún comentario al respecto? Parece ineficaz grep dos veces, pero funciona ...

Cuestiones relacionadas