¿Cómo encuentro los archivos en el directorio actual que no contienen la palabra foo
(usando grep
)?
¿Cómo encuentro los archivos en el directorio actual que no contienen la palabra foo
(usando grep
)?
Respuestas:
Si su grep tiene la opción -L
(o --files-without-match
):
$ grep -L "foo" *
GREP_OPTIONS='--exclude-dir=.svn --exclude-dir=.git'
: ^)
-rL
lugar de -L
hacer coincidir subdirectorios
grep -L 'foo' -- *
el estándar es que los comandos que toman opciones largas se usan --
para indicar que no hay más opciones después de este punto.
Echa un vistazo a ack
. Hace la .svn
exclusión automáticamente, le da expresiones regulares de Perl y es una simple descarga de un solo programa de Perl.
El equivalente de lo que está buscando debe ser, en ack
:
ack -L foo
Puedes hacerlo solo con grep (sin encontrar).
grep -riL "foo" .
Esta es la explicación de los parámetros utilizados en grep
-L, --files-without-match
each file processed.
-R, -r, --recursive
Recursively search subdirectories listed.
-i, --ignore-case
Perform case insensitive matching.
Si usa l
(en minúsculas) obtendrá lo contrario (archivos con coincidencias)
-l, --files-with-matches
Only the names of files containing selected lines are written
El siguiente comando me da todos los archivos que no contienen el patrón foo
:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep 0
grep '0$'
también coincidiría con archivos con múltiplos de 10 líneas! Debe grep ':0$'
al final verificar un ': 0' explícito al final de la línea. Entonces solo obtendrá archivos con cero líneas coincidentes.
El siguiente comando excluye la necesidad de encontrar para filtrar las svn
carpetas mediante el uso de un segundo grep
.
grep -rL "foo" ./* | grep -v "\.svn"
Realmente necesitarás:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep :0\$
Problema
Necesito refactorizar un proyecto grande que usa .phtml
archivos para escribir HTML usando código PHP en línea. Quiero usar plantillas de bigote en su lugar. Quiero encontrar cualquier .phtml
giles que no contenga la cadena, new Mustache
ya que aún deben reescribirse.
Solución
find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
Explicación
Antes de las tuberías:
Encontrar
find .
Encuentra archivos recursivamente, comenzando en este directorio
-iname '*.phtml'
El nombre del archivo debe contener .phtml
( i
esto hace que no distinga entre mayúsculas y minúsculas)
-exec 'grep -H -E -o -c 'new Mustache' {}'
Ejecute el grep
comando en cada una de las rutas coincidentes
Grep
-H
Siempre imprima encabezados de nombre de archivo con líneas de salida.
-E
Interprete el patrón como una expresión regular extendida (es decir, forzar a grep a comportarse como egrep).
-o
Imprime solo la parte coincidente de las líneas.
-c
Solo un recuento de líneas seleccionadas se escribe en la salida estándar.
Esto me dará una lista de todas las rutas de archivos que terminan en .phtml
, con un recuento de la cantidad de veces que la cadena new Mustache
ocurre en cada una de ellas.
$> find . -iname '*.phtml$' -exec 'grep -H -E -o -c 'new Mustache' {}'\;
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/orders.phtml:1
./app/MyApp/Customer/View/Account/banking.phtml:1
./app/MyApp/Customer/View/Account/applycomplete.phtml:1
./app/MyApp/Customer/View/Account/catalogue.phtml:1
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0
La primera tubería grep :0$
filtra esta lista para incluir solo líneas que terminan en :0
:
$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0
La segunda tubería sed 's/..$//'
elimina los dos caracteres finales de cada línea, dejando solo las rutas de archivo.
$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml
./app/MyApp/Customer/View/Account/studio.phtml
./app/MyApp/Customer/View/Account/classadd.phtml
./app/MyApp/Customer/View/Account/orders-trade.phtml
Mi grep no tiene ninguna opción -L. Encuentro la solución para lograr esto.
Las ideas son:
marque la diferencia entre el archivo de volcado 2 con el comando diff.
grep 'foo' *.log | cut -c1-14 | uniq > txt1.txt
grep * *.log | cut -c1-14 | uniq > txt2.txt
diff txt1.txt txt2.txt | grep ">"
diff
secuencia de salida entre dos (creo que rodea los comandos con paréntesis, y también hay un paréntesis angular en alguna parte), si su sistema lo admite, lo que supongo es la pregunta, ya que no es compatiblegrep -L
find *20161109* -mtime -2|grep -vwE "(TRIGGER)"
Puede especificar el filtro en "buscar" y la cadena de exclusión en "grep -vwE". Use mtime en find si necesita filtrar también en el tiempo modificado.
Como comentó @tukan, hay un informe de error abierto para Ag con respecto a la bandera -L
/ --files-without-matches
:
Como hay poco progreso en el informe de error, no se debe confiar en la -L
opción mencionada a continuación , siempre y cuando el error no se haya resuelto. Utilice diferentes enfoques presentados en este hilo en su lugar. Citando un comentario para el informe de error [énfasis mío]:
¿Alguna actualización sobre esto?
-L
ignora completamente las coincidencias en la primera línea del archivo. Parece que si esto no se va a solucionar pronto, la bandera debería eliminarse por completo, ya que efectivamente no funciona como se anuncia .
Como una alternativa poderosa a grep
, podría usar The Silver Searcher - Ag :
Una herramienta de búsqueda de código similar a ack, con un enfoque en la velocidad.
Mirando man ag
, encontramos la opción -L
u --files-without-matches
:
... OPTIONS ... -L --files-without-matches Only print the names of files that don´t contain matches.
Es decir, para buscar de forma recursiva archivos que no coinciden foo
, desde el directorio actual:
ag -L foo
Para buscar solo en el directorio actual archivos que no coincidan foo
, simplemente especifique --depth=0
la recursividad:
ag -L foo --depth 0
-L
error - github.com/ggreer/the_silver_searcher/issues/238
grep -irnw "filepath" -ve "pattern"
o
grep -ve "pattern" < file
el comando anterior nos dará el resultado cuando -v encuentre el inverso del patrón que se está buscando
-l
opción para imprimir solo el nombre del archivo; pero esto todavía imprime los nombres de cualquier archivo que contenga cualquier línea que no contenga el patrón. Creo que el OP quiere encontrar los archivos que no contienen ninguna línea que contenga el patrón.
El siguiente comando podría ayudarlo a filtrar las líneas que incluyen la subcadena "foo".
cat file | grep -v "foo"
cat
.