2012-01-16 15 views
6

No estoy seguro de por qué esa redirección proporcionada en el código no funciona. Cada vez que ejecuto el script, el archivo de salida siempre está vacío. ¿Alguien tiene una idea sobre eso?Redirigir la salida de grep al archivo

Gracias.

#!/bin/sh 

LOOK_FOR="DefaultProblem" 
FILES=`ls plugins/*source*.jar` 

for i in $FILES 
    do 
    # echo "Looking in $i ..." 
    unzip -p $i | grep -i $LOOK_FOR > output #> /dev/null 
    if [ $? == 0 ] 
    then 
     echo ">>>> Found $LOOK_FOR in $i <<<<" 
    fi 
    done 
+2

Para referencia futura, "no funciona" no es una buena descripción. Cuéntanos * cómo * no funciona. –

+1

Es probable que sea * muy * relevante para cualquier pregunta futura que pueda tener, suponiendo que tome en serio mi consejo. No dije algo relevante al problema porque ya había sido respondido. Esto es para lo que son los comentarios. Realmente estoy tratando de ayudarte aquí. Por favor considere la posibilidad de que pueda tener un punto válido. –

+1

@fabricemarcelin: publicar un comentario * está * participando en la discusión –

Respuesta

9

Es posible que desee utilizar >> (Añadir) en lugar de > (sobrescribir) para la redirección como:

unzip -p $i | grep -i $LOOK_FOR >> output #> /dev/null 

Puesto que usted está ejecutando este comando en un bucle y la sobreescritura de archivos output cada vez, podría estar en blanco al final si el último comando con grep no encuentra ninguna línea coincidente en la salida de descompresión.

+0

Impresionante, funciona como un encanto. Totalmente no pensé en eso. Gracias – fabricemarcelin

+0

De nada, me alegro de que haya funcionado para ti. – anubhava

3

tiene tres problemas

  1. No trate de analizar la salida de ls. En su lugar, simplemente use for i in plugins/*source*.jar La razón principal es que su script se romperá completamente en cualquier archivo que tenga espacios en sus nombres. Ver this link para una letanía de razones por las que no se va a analizar ls
  2. Es necesario utilizar >> en lugar de > ya que éste se sobrescribirá el archivo de salida en cada iteración del bucle. El primero se anexar a él
  3. ¡Use más presupuestos! Querrá citar las variables para asegurarse de que no están sujetas a la división de palabras

Además, puede alinear la prueba if. Así que poner todos juntos tenemos:

#!/bin/sh 

LOOK_FOR="DefaultProblem" 
for i in plugins/*source*.jar 
do 
    # echo "Looking in $i ..." 
    if unzip -p "$i" | grep -i "$LOOK_FOR" >> output #> /dev/null 
    then 
     echo ">>>> Found $LOOK_FOR in $i <<<<" 
    fi 
done 
+0

Gracias por el consejo, lo tendré en cuenta. – fabricemarcelin

+2

Como esto busca varios archivos pero lo hace de uno en uno, el resultado 'grep' como se muestra no contendrá un nombre de archivo que identifique de qué archivo proviene cada línea. Algunas veces puedes arreglar eso agregando '/ dev/null' a la línea de comando' grep'; desafortunadamente, esta no es una de esas ocasiones. Necesitarías agregar: '| sed "s% ^% $ i:%" 'antes de la redirección' >> '. –

+0

@JonathanLeffler Buena idea, pero en este caso sugeriría simplemente usar el indicador '-l' para' grep' – SiegeX

0

En lugar de un for loop y un if conditional se puede hacer todo en un find comando

find /path/to/plugins -name "*source*.jar" -exec sh -c 'unzip -l "{}" | grep -q DefaultProblem' \; -print 
+0

Incluso utilizando la salida de 'find' también se romperá con los archivos que tienen espacios en su nombre. La forma de arreglar esto es mediante el indicador '-print0' para' encontrar' y un ciclo 'while IFS = -r -d '' line' con bash usando la sustitución de proceso. O mejor aún use globstar de Bash 4 – SiegeX

+0

Verdadero ... Su respuesta realmente cubre todos los problemas potenciales. Seguiré adelante y eliminaré el mío. :) –

+0

@SiegeX Han modificado la respuesta para ofrecer algo nuevo. –

2

Puede redirigir la salida de todo el bucle:

#!/bin/sh 

LOOK_FOR="DefaultProblem" 
FILES=`ls plugins/*source*.jar` 

for i in $FILES ; do 
    # echo "Looking in $i ..." 1>&2 
    unzip -p $i | grep -i $LOOK_FOR 
    if [ $? == 0 ] ; then 
     echo ">>>> Found $LOOK_FOR in $i <<<<" 1>&2 
    fi 
done > output 

Tenga en cuenta que he redirigido los mensajes de diagnóstico a stderr.

Cuestiones relacionadas