¿Cómo puedo conseguir` encontrar ' para ignorar.directorios svn?


A menudo uso el comando find para buscar en el código fuente, eliminar archivos, lo que sea. Es molesto, porque Subversion almacena duplicados de cada archivo en sus directorios .svn/text-base/ mis búsquedas simples terminan obteniendo muchos resultados duplicados. Por ejemplo, quiero buscar recursivamente uint en múltiples archivos messages.h y messages.cpp:

# find -name 'messages.*' -exec grep -Iw uint {} +
./messages.cpp:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./messages.cpp:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./messages.cpp:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./messages.cpp:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./messages.cpp:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./.svn/text-base/messages.cpp.svn-base:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./virus/messages.cpp:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/messages.cpp:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/messages.h:    void _progress(const std::string &fileName, uint scanCount);
./virus/messages.h:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/messages.h:    uint        _scanCount;
./virus/.svn/text-base/messages.cpp.svn-base:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.cpp.svn-base:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.h.svn-base:    void _progress(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base:    uint        _scanCount;

¿Cómo puedo decirle a find que ignore los directorios .svn?


Actualizar : Si actualiza su cliente SVN a la versión 1.7 esto ya no es un problema.

Una característica clave de los cambios introducidos en Subversion 1.7 es la centralización del almacenamiento de metadatos de la copia de trabajo en una única ubicación. En lugar de un directorio .svn en cada directorio de la copia de trabajo, las copias de trabajo de Subversion 1.7 tienen solo un directorio .svn-en la raíz de la copia de trabajo. Este directorio incluye (entre otras cosas) una base de datos respaldada por SQLite que contiene todos los metadatos que Subversion necesita para funcionar copia.

Author: John Kugelman, 2010-02-23

19 answers

Para buscar, puedo sugerirle que mire ack ? Es un find consciente del código fuente, y como tal ignorará automáticamente muchos tipos de archivos, incluida la información del repositorio de código fuente como la anterior.

 67
Author: Brian Agnew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-22 22:13:17

¿Por qué no solo

find . -not -iwholename '*.svn*'

El predicado no niega todo lo que tiene .svn en cualquier lugar del camino.

Así que en su caso sería

find -not -iwholename '*.svn' -name 'messages.*' -exec grep -Iw uint {} + \;
 276
Author: whaley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-20 01:44:10

Como sigue:

find . -path '*/.svn*' -prune -o -print

O, alternativamente, basado en un directorio y no en un prefijo de ruta:

find . -name .svn -a -type d -prune -o -print
 136
Author: Kaleb Pederson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-22 22:20:31

Ignorar .svn, .git y otros directorios ocultos (comenzando con un punto), intente:

find . -type f -not -path '*/\.*'

Sin embargo, si el propósito de usar find es buscar dentro de los archivos, puede intentar usar estos comandos:

  • git grep - comando especialmente diseñado para buscar patrones dentro del repositorio Git.
  • ripgrep - que por defecto ignora los archivos ocultos y los archivos especificados en .gitignore.

Relacionado: ¿Cómo encuentro todos los archivos que contienen ¿texto en Linux?

 27
Author: kenorb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-20 12:00:36

Esto es lo que haría en su caso:

find . -path .svn -prune -o -name messages.* -exec grep -Iw uint {} +

El comando integrado de Emacs rgrep ignora el directorio .svn, y muchos más archivos que probablemente no le interesen al realizar un find | grep. Esto es lo que usa por defecto:

find . \( -path \*/SCCS -o -path \*/RCS -o -path \*/CVS -o -path \*/MCVS \
          -o -path \*/.svn -o -path \*/.git -o -path \*/.hg -o -path \*/.bzr \
          -o -path \*/_MTN -o -path \*/_darcs -o -path \*/\{arch\} \) \
     -prune -o \
       \( -name .\#\* -o -name \*.o -o -name \*\~ -o -name \*.bin -o -name \*.lbin \
          -o -name \*.so -o -name \*.a -o -name \*.ln -o -name \*.blg \
          -o -name \*.bbl -o -name \*.elc -o -name \*.lof -o -name \*.glo \
          -o -name \*.idx -o -name \*.lot -o -name \*.fmt -o -name \*.tfm \
          -o -name \*.class -o -name \*.fas -o -name \*.lib -o -name \*.mem \
          -o -name \*.x86f -o -name \*.sparcf -o -name \*.fasl -o -name \*.ufsl \
          -o -name \*.fsl -o -name \*.dxl -o -name \*.pfsl -o -name \*.dfsl \
          -o -name \*.p64fsl -o -name \*.d64fsl -o -name \*.dx64fsl -o -name \*.lo \
          -o -name \*.la -o -name \*.gmo -o -name \*.mo -o -name \*.toc \
          -o -name \*.aux -o -name \*.cp -o -name \*.fn -o -name \*.ky \
          -o -name \*.pg -o -name \*.tp -o -name \*.vr -o -name \*.cps \
          -o -name \*.fns -o -name \*.kys -o -name \*.pgs -o -name \*.tps \
          -o -name \*.vrs -o -name \*.pyc -o -name \*.pyo \) \
     -prune -o \
     -type f \( -name pattern \) -print0 \
     | xargs -0 -e grep -i -nH -e regex

Ignora los directorios creados por la mayoría de los sistemas de control de versiones, así como los archivos generados para muchos lenguajes de programación. Puede crear un alias que invoque este comando y reemplazar find y grep patrones para su específico problema.

 17
Author: Antoine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-21 12:30:10

GNU find

find .  ! -regex ".*[/]\.svn[/]?.*"
 12
Author: ghostdog74,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 00:45:18

Utilizo grep para este propósito. Pon esto en tu ~/.bashrc

export GREP_OPTIONS="--binary-files=without-match --color=auto --devices=skip --exclude-dir=CVS --exclude-dir=.libs --exclude-dir=.deps --exclude-dir=.svn"

Grep utiliza automáticamente estas opciones en la invocación

 10
Author: Ronny Brendel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-08 15:17:07

Crea un script llamado ~/bin/svnfind:

#!/bin/bash
#
# Attempts to behave identically to a plain `find' command while ignoring .svn/
# directories.

OPTIONS=()
PATHS=()
EXPR=()

while [[ $1 =~ ^-[HLP]+ ]]; do
    OPTIONS+=("$1")
    shift
done

while [[ $# -gt 0 ]] && ! [[ $1 =~ '^[-(),!]' ]]; do
    PATHS+=("$1")
    shift
done

# If user's expression contains no action then we'll add the normally-implied
# `-print'.
ACTION=-print

while [[ $# -gt 0 ]]; do
    case "$1" in
       -delete|-exec|-execdir|-fls|-fprint|-fprint0|-fprintf|-ok|-print|-okdir|-print0|-printf|-prune|-quit|-ls)
            ACTION=;;
    esac

    EXPR+=("$1")
    shift
done

if [[ ${#EXPR} -eq 0 ]]; then
    EXPR=(-true)
fi

exec -a "$(basename "$0")" find "${OPTIONS[@]}" "${PATHS[@]}" -name .svn -type d -prune -o '(' "${EXPR[@]}" ')' $ACTION

Este script se comporta de forma idéntica a un comando find simple, pero elimina los directorios .svn. De lo contrario, el comportamiento es idéntico.

Ejemplo:

# svnfind -name 'messages.*' -exec grep -Iw uint {} +
./messages.cpp:            Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./messages.cpp:    Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./messages.cpp:                Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./messages.cpp:            Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./messages.cpp:        Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./messages.cpp:        for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./virus/messages.cpp:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/messages.cpp:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/messages.h:    void _progress(const std::string &fileName, uint scanCount);
./virus/messages.h:    ProgressMessage(const std::string &fileName, uint scanCount);
./virus/messages.h:    uint        _scanCount;
 8
Author: John Kugelman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-10 16:26:09

find . | grep -v \.svn

 8
Author: me.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-22 13:52:13

¿Por qué no canalizar su comando con grep que es fácilmente comprensible:

your find command| grep -v '\.svn'
 7
Author: Vijay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-21 11:43:31

Solo pensé en agregar una alternativa simple a los mensajes de Kaleb y otros (que detallaban el uso de la opción find -prune , ack, repofind comandos, etc.) que es particularmente aplicable al uso que ha descrito en la pregunta (y cualquier otro uso similar):

  1. Para el rendimiento, siempre debe intentar usar find ... -exec grep ... + (gracias Kenji por señalar esto) o find ... | xargs egrep ... (portable) o find ... -print0 | xargs -0 egrep ... (GNU; funciona con nombres de archivo que contienen espacios) en lugar de find ... -exec grep ... \;.

    El formulario find ... -exec ... + y find | xargs no bifurca egrep para cada archivo, sino para un montón de archivos a la vez, lo que resulta en una ejecución mucho más rápida.

  2. Al usar el formulario find | xargs también puede usar grep para podar fácil y rápidamente .svn (o cualquier directorio o expresión regular), es decir, find ... -print0 | grep -v '/\.svn' | xargs -0 egrep ... (útil cuando necesita algo rápido y no se molesta en recordar cómo configurar la lógica find's -prune.)

    El enfoque find | grep | xargs es similar a GNU find's -regex opción (ver ghostdog74' s post), pero es más portable (también funcionará en plataformas donde GNU find no está disponible.)

 5
Author: vladr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-27 14:05:14

En un repositorio de código fuente, generalmente quiero hacer cosas solo con los archivos de texto.

La primera línea son todos los archivos, excluyendo los archivos de repositorio CVS, SVN y GIT.

La segunda línea excluye todos los archivos binarios.

find . -not \( -name .svn -prune -o -name .git -prune -o -name CVS -prune \) -type f -print0 | \
xargs -0 file -n | grep -v binary | cut -d ":" -f1
 4
Author: rickfoosusa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-07 19:29:55

Utilizo find con las opciones-not-path. No he tenido buena suerte con Prune.

find .  -name "*.groovy" -not -path "./target/*" -print

Encontrará los archivos groovy que no están en la ruta del directorio de destino.

 3
Author: scott m gardner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-13 00:42:01

Intente findrepo que es un envoltorio simple alrededor de find / grep y mucho más rápido que ack Lo usarías en este caso como:

findrepo uint 'messages.*'
 2
Author: pixelbeat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-23 01:11:04

wcfind es un script de find wrapper que uso para eliminar automáticamente .directorios svn.

 2
Author: leedm777,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-08 07:49:41

Para resolver este problema, simplemente puede usar esta condición de búsqueda:

find \( -name 'messages.*' ! -path "*/.svn/*" \) -exec grep -Iw uint {} +

Puede agregar más restricciones como esta:

find \( -name 'messages.*' ! -path "*/.svn/*" ! -path "*/CVS/*" \) -exec grep -Iw uint {} +

Puede encontrar más información sobre esto en la sección de la página de manual "Operadores": http://unixhelp.ed.ac.uk/CGI/man-cgi?find

 2
Author: Code-Source,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-17 15:21:09

Tenga en cuenta que si lo hace

find . -type f -name 'messages.*'

Entonces -print se implica cuando toda la expresión (-type f -name 'messages.*') es verdadera, porque no hay 'acción' (como -exec).

Mientras que, para dejar de descender en ciertos directorios, debe usar cualquier cosa que coincida con esos directorios y seguirlo por -prune (que está destinado a dejar de descender en directorios); así:

find . -type d -name '.svn' -prune

Esto se evalúa a Verdadero para el .directorios svn, y podemos usar boolean cortocircuito siguiendo esto por -o (O), después de lo cual lo que sigue después de -o solo se comprueba cuando la primera parte es Falsa, por lo tanto es no a.directorio svn. En otras palabras, lo siguiente:

find . -type d -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}

Solo evaluará lo que es correcto de -o, a saber, -name 'message.*' -exec grep -Iw uint {}, para los archivos QUE NO están dentro .directorios svn.

Tenga en cuenta que porque .svn es probable que siempre un directorio (y no, por ejemplo, un archivo), y en este caso ciertamente no coincide con el nombre mensaje.* ', también podrías dejar fuera el -type d y hacer:

find . -name '.svn' -prune -o -name 'message.*' -exec grep -Iw uint {}

Finalmente, tenga en cuenta que si omite cualquier acción (-exec es una acción), diga así:

find . -name '.svn' -prune -o -name 'message.*'

Entonces la acción -print está implícita, pero se aplicará a TODA la expresión, incluida la parte -name '.svn' -prune -o y, por lo tanto, imprimirá todo .directorios svn así como el ' message.* 'archivos, que probablemente no es lo que quieres. Por lo tanto, siempre debe usar una 'acción' en el lado derecho del booleano expresión cuando se usa -prune de esta manera. Y cuando esa acción está imprimiendo tienes que añadirla explícitamente, así:

find . -name '.svn' -prune -o -name 'message.*' -print

 2
Author: Carlo Wood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-26 23:54:45

Esto funciona para mí en el prompt de Unix

Gfind . \ (- not-wholename'*\.svn*'\) - escriba mensajes f-name'.*' - exec grep-Iw uint {} +

El comando anterior listará los ARCHIVOS que no están con .svn y haz el grep que mencionaste.

 1
Author: Felix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-09 06:51:41

Normalmente canalizo la salida a través de grep una vez más eliminando .svn, en mi uso no es mucho más lento. ejemplo típico:

find -name 'messages.*' -exec grep -Iw uint {} + | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'

O

find . -type f -print0 | xargs -0 egrep messages. | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'
 1
Author: geminiimatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-19 18:35:22