linux - una - svn subir archivos




¿Cómo puedo hacer que `find` ignore los directorios.svn? (13)

¿Por qué no canalizas tu comando con grep que es fácilmente comprensible?

your find command| grep -v '\.svn'

A menudo utilizo el comando Buscar para buscar a través del código fuente, borrar archivos, lo que sea. Resulta 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 varios 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 ?

Actualización : 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 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 un solo 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 esa copia de trabajo.


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

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

La primera línea es todos los archivos, excepto 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

Encontrar GNU

find .  ! -regex ".*[/]\.svn[/]?.*"

Esto funciona para mí en el indicador de Unix.

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

El comando anterior enumerará los ARCHIVOS que no están con .svn y hará el grep que mencionó.


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'

Para 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 : git grep especialmente diseñado para buscar patrones dentro del repositorio Git.
  • ripgrep - que de forma predeterminada ignora los archivos ocultos y los archivos especificados en .gitignore .

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


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 restricción 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 man "Operadores": http://unixhelp.ed.ac.uk/CGI/man-cgi?find


Simplemente pensé que agregaría una alternativa simple a las publicaciones de Kaleb y otros (que detallaban el uso de la opción find -prune , ack , comandos de repofind , etc.) que es particularmente aplicable al uso que ha descrito en la pregunta (y cualquier otros usos similares):

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

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

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

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


Tenga en cuenta que si lo hace

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

entonces -print está implícito cuando toda la expresión ( -type f -name 'messages.*' ) es verdadera, porque no hay 'action' (como -exec ).

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

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

Esto se evalúa como Verdadero para los directorios .svn, y podemos usar el cortocircuito booleano siguiendo esto mediante -o (O), después de lo cual lo que sigue después de -o solo se verifica cuando la primera parte es Falso, por lo tanto no es un 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 archivos que NO estén dentro de los directorios .svn.

Tenga en cuenta que debido a que .svn es probable que siempre sea un directorio (y no por ejemplo un archivo), y en este caso ciertamente no coincide con el nombre 'mensaje. *', Es mejor que -type d el -type d y haga:

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.*'

luego, la acción -print está implícita pero se aplicará a la expresión ENTERA, incluido el nombre -name '.svn' -prune -o y, por lo tanto, imprimirá todos los directorios .svn, así como los archivos' mensaje. * ', que probablemente no sean Lo que quieras. Por lo tanto, siempre debe usar una 'acción' en el lado derecho de la expresión booleana cuando use -prune de esta manera. Y cuando esa acción se está imprimiendo, tienes que agregarla explícitamente, así:

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


Yo uso 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


porque no solo

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

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

Así que en tu caso sería

find -not -iwholename '*.svn*' -name 'messages.*' -exec grep -Iw uint {} + \;

find . | grep -v \.svn





svn