2012-04-29 13 views
6

Estoy tratando de hacer una instrucción if/then, donde si hay un resultado no vacío de un comando ls | grep something entonces quiero ejecutar algunas instrucciones. No sé la sintaxis que debería estar usando. He intentado varias variaciones de este:Bash shell `if` comando devuelve algo` then` hacer algo

if [[ `ls | grep log ` ]]; then echo "there are files of type log"; 
+0

http://mywiki.wooledge.org/BashFAQ/004 ("¿Cómo puedo verificar si un directorio está vacío o no? ¿Cómo puedo verificar cualquier archivo * .mpg, o coun ¿Cuántos hay? ") es de alguna manera relevante para el problema inmediato que tenemos entre manos. –

Respuesta

18

Bueno, eso es estrecha, pero hay que terminar el if con fi.

Además, if simplemente ejecuta un comando y ejecuta el código condicional si el comando tiene éxito (sale con el código de estado 0), que grep hace solo si encuentra al menos una coincidencia. Así que no es necesario para comprobar la salida:

if ls | grep -q log; then echo "there are files of type log"; fi 

Si estás en un sistema con una versión más antigua o no de GNU grep que no admite la opción -q ("silencioso"), se se puede lograr el mismo resultado mediante la reorientación de su producción a /dev/null:

if ls | grep log >/dev/null; then echo "there are files of type log"; fi 

Pero desde ls también devuelve distinto de cero si no encuentra un archivo especificado, se puede hacer lo mismo sin la grep en absoluto, como en D Respuesta de .Shawley:

if ls *log* >&/dev/null; then echo "there are files of type log"; fi 

También puede hacerlo utilizando sólo la cáscara, sin ni siquiera ls, aunque es un poco más prolijo:

for f in *log*; do 
    # even if there are no matching files, the body of this loop will run once 
    # with $f set to the literal string "*log*", so make sure there's really 
    # a file there: 
    if [ -e "$f" ]; then 
    echo "there are files of type log" 
    break 
    fi 
done 

Mientras usted está utilizando fiesta específicamente, se puede establecer la opción nullglob para simplificar que algo:

shopt -s nullglob 
for f in *log*; do 
    echo "There are files of type log" 
    break 
done 
+0

gracias - eso es perfecto. –

1

el if incorporado ejecuta un comando shell y selecciona el bloque basado en el valor de retorno del comando. ls devuelve un código de estado distinto si no encuentra los archivos solicitados, por lo que no hay necesidad de la parte grep. La utilidad [[ es en realidad un comando incorporado de bash, IIRC, que realiza operaciones aritméticas. Podría estar equivocado en esa parte ya que rara vez me alejo mucho de la sintaxis del shell Bourne.

De todos modos, si se pone todo esto junto, entonces se termina con el siguiente comando:

if ls *log* > /dev/null 2>&1 
then 
    echo "there are files of type log" 
fi 
+0

Gracias por la explicación, pero estaba bastante decidido a usar grep. Tengo la intención de filtrar a través de varias reglas de expresión regulares, y tal vez filtrar la salida de otros comandos además de ls. Estaba usando ls como ejemplo para que la resolución de mi formato me permita escribir muchos más comandos similares. Cheers, ~) –

+1

@BillyMoon - es posible que desee considerar el uso de 'find' en lugar de grepping la salida de' ls'.Si usa 'ls', entonces use la ruta completa para que no se sorprenda por el alias de alguien de' ls'. –

+0

@ D.Shawley también puede usar 'command ls', que elude ambos alias y funciones sin depender de una ruta específica al comando. –

2

o sin if; then; fi:

ls | grep -q log && echo 'there are files of type log' 

O incluso:

ls *log* &>/dev/null && echo 'there are files of type log' 
+0

Quiere decir '> &', no '&>'. –

Cuestiones relacionadas