Pregunta ¿Grep por esto y NO eso en un archivo?


¿Cómo puedo grep para archivos en una estructura de directorio que tienen este texto

addDesignControlChangeNotification

pero le falta este texto

removeDesignControlChangeNotification

¡Gracias!

Nota: Me refiero al directorio en el que comienza la secuencia de comandos y todos los subdirectorios.


0


origen


Hmm, en el directorio principal, o dir principal y subdirectorios? - Rich Homolka
Me refiero al directorio en el que iniciamos el script y todos los subdirectorios. Lo siento, eso no estaba claro antes. - Dan Rosenstark


Respuestas:


Aquí hay uno que está basado libremente en Rich Homolka's responder, pero funciona en árboles de directorios:

find . -type f  -exec grep -l addDesignControlChangeNotification {} \; | 
 while IFS= read -r file; do 
   grep -q removeDesignControlChangeNotification "$file" > /dev/null ; 
   [ $? -ne 0 ] && echo $file; 
 done

Todos los archivos devueltos contendrán addDesignControlChangeNotification pero no removeDesignControlChangeNotification.

EXPLICACIÓN:

  • find . -type f -exec grep -l foo {} \;: Esto imprimirá todos los archivos en cualquier subdirectorio del directorio actual que contenga la cadena foo. los -l bandera hace que grep solo imprima los nombres de los archivos coincidentes.

  • while read file : esto itera a través de cada archivo que se encuentra arriba, guardando su nombre en la variable $file.

  • grep -q bar "$file" > /dev/null : este comand loks para la cadena bar en cada uno de los archivos que contenía foo.

  • [ $? -ne 0 ] && echo $file; : Si el valor de retorno ($?) del grep el comando era 0 (es decir, si la cadena no estaba en el archivo), imprima el nombre del archivo.


1



Impresionante, estoy usando find . -name '*.m' -type f -exec grep -l addDesignControlChangeNotification {}...  que yo mismo agregué porque no lo mencioné en la pregunta;) ¡Gracias! - Dan Rosenstark


Esto debería funcionar:

FIRST=addDesignControlChangeNotification
SECOND=removeDesignControlChangeNotification
grep -l $FIRST * | while IFS= read -r FILE
do
    grep $SECOND "$FILE" &> /dev/null
    if [ $? -ne 0 ]
    then
        echo "File $FILE has $FIRST but not $SECOND"
    fi
done

2



Se ve muy bien, pero obtengo "Es un directorio" en lugar de entrar en esos directorios. ¿Alguna idea de lo que está mal? Gracias +1! - Dan Rosenstark
@Yar, puedes agregar un -r a la primera grep comando si desea recurse directorios. O puede usar mi respuesta;). - terdon


Un trazador de líneas:

comm -2 -3 <(grep -rl addDesignControlChangeNotification     . | sort ) \
           <(grep -rl removeDesignControlChangeNotification  . | sort )

grep -r es un grep recursivo, <() es sustitución de procesosy comm le muestra las líneas que un par de archivos (ordenados) tienen / no tienen en común. En este caso, solo queremos la salida de la columna 1: líneas en el primer archivo (donde "archivo" es realmente salida grep) que no están en el segundo.


0