Comment puis-je obtenir `find` pour ignorer les répertoires .svn?


227

J'utilise souvent la findcommande pour rechercher dans le code source, supprimer des fichiers, peu importe. Chose ennuyeuse, parce que Subversion stocke des doublons de chaque fichier dans ses .svn/text-base/répertoires, mes recherches simples finissent par obtenir de nombreux résultats en double. Par exemple, je veux rechercher récursivement uintdans plusieurs fichiers messages.het 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;

Comment puis-je dire findd'ignorer les .svnrépertoires?


Mise à jour : si vous mettez à niveau votre client SVN vers la version 1.7, ce n'est plus un problème.

Une caractéristique clé des changements introduits dans Subversion 1.7 est la centralisation du stockage des métadonnées de copie de travail en un seul emplacement. Au lieu d'un .svnrépertoire dans chaque répertoire de la copie de travail, les copies de travail de Subversion 1.7 n'ont qu'un seul .svnrépertoire, à la racine de la copie de travail. Ce répertoire comprend (entre autres) une base de données SQLite-soutenue qui contient tous les besoins de Subversion de métadonnées pour cette copie de travail.


4
Pour des performances, essayez d'utiliser à la find ... -print0 | xargs -0 egrep ...place de find ... -exec grep ...(ne se bifurque pas greppour chaque fichier, mais pour un tas de fichiers à la fois). En utilisant ce formulaire, vous pouvez également élaguer les .svnrépertoires sans utiliser l' -pruneoption de recherche, c'estfind ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...
vladr

3
@Vlad: Autant que je sache, utiliser -execavec +ne se bifurque pas greppour chaque fichier, tout en l'utilisant avec le ;fait. L'utilisation -execest en fait plus correcte que l'utilisation xargs. Veuillez noter que les commandes comme lsfont quelque chose même si la liste des arguments est vide, tandis que les commandes comme chmoddonnent une erreur s'il n'y a pas suffisamment d'arguments. Pour voir ce que je veux dire, essayez la commande suivante dans un répertoire qui n'a pas de script shell: find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755. Comparer avec celui - ci: find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'.
Siu Ching Pong -Asuka Kenji-

2
@ Vlad: De plus, grepsortir .svnn'est pas une bonne idée non plus. Bien qu'il findsoit spécialisé dans la gestion des propriétés des fichiers, il grepne l'est pas. Dans votre exemple, un fichier nommé '.svn.txt' sera également filtré par votre egrepcommande. Bien que vous puissiez modifier votre expression régulière en '^ / \. Svn $' , ce n'est toujours pas une bonne pratique de le faire. Le -pruneprédicat de findfonctionne parfaitement pour filtrer un fichier (par nom de fichier, ou horodatage de création, ou quelle que soit la condition que vous avez fournie). C'est comme si même si vous pouvez tuer un cafard à l'aide d'une grosse épée, cela ne signifie pas que c'est la façon suggérée de le faire :-).
Siu Ching Pong -Asuka Kenji-

3
Passer à Git a résolu ce problème (parmi beaucoup d'autres). In crée uniquement un dossier .git à la racine de la copie de travail, pas dans tous les dossiers comme SVN. En outre, le dossier .git ne contient pas de fichiers simples qui pourraient être confondus avec vos fichiers réels par les mêmes noms.
Tronic

3
2Dan Moulding: svn 1.7 ne crée qu'un seul répertoire .svn de premier niveau
ccpizza

Réponses:


65

Pour la recherche, puis-je vous suggérer de regarder ack ? Il s'agit d'un code source find, et en tant que tel, il ignorera automatiquement de nombreux types de fichiers, y compris les informations de référentiel de code source telles que celles ci-dessus.


3
J'aime ackbeaucoup, mais je l'ai trouvé beaucoup plus lent que find -type f -name "*.[ch]" | xargs greplorsqu'il s'agissait d'une grande base de code.
John Ledbetter

63
John, je suis l'auteur de ack, et si vous pouvez me donner des détails sur les problèmes de vitesse entre ack et grep, j'apprécierais. Ils ont été complètement comparables dans tous les cas que j'ai trouvés. Faites-le moi savoir sur github.com/petdance/ack/issues ou envoyez-moi un e-mail sur andy sur petdance.com. Merci.
Andy Lester

63
Les gars, c'est une astuce, mais certainement pas une réponse à la question! :)
dolzenko

8
N'est-ce pas ackfacturé comme meilleur grep, pas comme source-conscient find? Quelques exemples d'utilisation pour le remplacer en findferaient une vraie réponse.
michiakig

3
C'est une réponse à la question qu'il ne savait pas qu'il posait. =)
Frungi

293

pourquoi pas

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

Le prédicat -not annule tout ce qui contient .svn n'importe où dans le chemin.

Donc, dans votre cas, ce serait

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

5
Super gros +1 pour "-not" et "-iwholename". Ack est merveilleux et je l'utilise, mais find / exec a toujours ses utilisations.
David Blevins

9
La seule réponse qui a réellement répondu à la question d'origine.
Brendon Crawford

14
Je suis loin de mon élément et je suis sûr que je serai critiqué pour ce commentaire, mais apparemment -not et -wholename ne sont pas conformes à POSIX. J'ai utilisé ! à la place de -not et -path à la place de -iwholename et a obtenu les mêmes résultats. Selon mes pages de manuel (Ubuntu 12.04), cette syntaxe est compatible POSIX.
John

1
@whaley Vous avez dit '*.svn*'au début mais ensuite '*.svn'. Quelle est la bonne? Les deux fonctionnent-ils? Je pense que ça devrait probablement l'être '*.svn*'?
Keith M

1
@KeithM grande prise en fait. Cette réponse est assise ici depuis des années et je ne pense pas que quiconque ait compris cela jusqu'à présent.
whaley

141

Comme suit:

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

Ou bien, basé sur un répertoire et non sur un préfixe de chemin:

find . -name .svn -a -type d -prune -o -print

14
@Kaleb: Salut. Je suggère find . -type d -name .svn -prune -o -printcar c'est un peu plus rapide. Selon la norme POSIX , les expressions sont évaluées une par une, dans l'ordre spécifié. Si la première expression de -aest false, la seconde expression ne sera pas évaluée (également appelée court-circuit et évaluation ).
Siu Ching Pong -Asuka Kenji-

2
@Kaleb: Comme comparer le type de fichier (équivalent à tester si un bit est défini dans un entier) est plus rapide que comparer le nom de fichier (équivalent à une comparaison de chaîne, qui est O (n)), mettre -type davant -name .svnest théoriquement plus efficace. Cependant, il est généralement insignifiant, sauf si vous avez une très grande arborescence de répertoires.
Siu Ching Pong -Asuka Kenji-

5
@ SiuChingPong-AsukaKenji - non, comparer uniquement le nom de fichier est plus rapide car -type nécessite un appel stat (2) sur chaque fichier. Cependant, le nom de fichier fait partie de la réponse readdir (3).
hraban

3
@JonathanHartley Vous manquez le -printdans le cadre de la dernière expression. Quelque chose comme find . -name .git -prune -o \( -type f -name LICENSE -print \)fonctionne comme prévu.
sschuberth

1
Si vous voulez ignorer les deux .git et .svn et liste les autres répertoires que, find . -name .svn -prune -o -name .git -prune -o -type d -print. Cela pourrait être quelques millisecondes plus rapide -type davant les deux -name, mais cela ne vaut pas la peine d'être tapé.
JPaget

34

Pour ignorer .svn, .gitet d'autres répertoires cachés (commençant par un point), essayez:

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

Cependant, si le but de l'utilisation findest la recherche dans les fichiers, vous pouvez essayer d'utiliser ces commandes:

  • git grep - commande spécialement conçue pour rechercher des modèles dans le référentiel Git.
  • ripgrep- qui ignore par défaut les fichiers cachés et les fichiers spécifiés dans .gitignore.

Connexes: Comment trouver tous les fichiers contenant du texte spécifique sur Linux?


Meilleure réponse imo. Les autres essaient d'expliquer des choses qui ne répondent pas à la simple question.
Anthony

19

Voici ce que je ferais dans votre cas:

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

La rgrepcommande intégrée d' Emacs ignore le .svnrépertoire et bien d'autres fichiers qui ne vous intéressent probablement pas lors de l'exécution d'un find | grep. Voici ce qu'il utilise par défaut:

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

Il ignore les répertoires créés par la plupart des systèmes de contrôle de version, ainsi que les fichiers générés pour de nombreux langages de programmation. Vous pouvez créer un alias qui invoque cette commande et remplacer findet des grepmodèles pour vos problèmes spécifiques.


12

GNU find

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

Je chargeais les chemins de répertoire dans un tableau que PHP devait traiter. Les autres réponses plus haut (pour une raison quelconque) n'ont pas filtré les fichiers dans la recherche (malgré le -type d) - cette réponse l'a fait. +1
be hollenbeck

11

J'utilise grep à cet effet. Mettez ceci dans votre ~ / .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 utilise automatiquement ces options lors de l'invocation


1
Il convient de noter que «grep» n'a gagné l'option «--exclude-dir» qu'il y a un an ou deux. Les distributions Linux récentes l'incluent, mais si je me souviens bien, j'ai dû compiler mon propre grep (ou demander à homebrew de le faire) sur OSX.
Jonathan Hartley

J'utilise une variante mineure de cela. Mon .bashrc crée une fonction Bash 'grp', qui est définie comme GREP_OPTIONS=xxx grep "$@". Cela signifie que la variable GREP_OPTIONS n'est définie que pour les instances de grep que j'exécute manuellement à l'aide de 'grp'. Cela signifie que je ne reçois jamais de situation où j'exécute un outil et, en interne, il appelle grep, mais l'outil est confus car grep ne se comporte pas comme prévu. En outre, j'ai une deuxième fonction «grpy», qui appelle «grp», mais ajoute --include=*.py, pour simplement rechercher des fichiers Python.
Jonathan Hartley

En fait, après réflexion, le faire à ma façon n'a plus du tout besoin d'utiliser GREP_OPTIONS. J'ai maintenant juste une fonction shell 'grp' qui appelle grep --exclude=tags --exclude_dir=.git ...etc... "$@". J'aime que cela fonctionne comme «ack», mais je garde la conscience et le contrôle de ce qu'il fait.
Jonathan Hartley

9

find . | grep -v \.svn


Vous devez vous échapper .dans l' .svnexpression régulière.
vladr

4
Utilisez --fixed-strings avec grep: | fgrep -v /.svn/ou `| grep -F -v / .svn / `pour exclure exactement le répertoire et non les fichiers avec" .svn "dans leur nom.
Stephen P

8

Pourquoi ne dirigez-vous pas votre commande avec grep qui est facilement compréhensible:

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

Vous devez vous échapper .dans l' .svnexpression régulière.
vladr

@Yclian sans l'ombre d'un doute; si vous ne le faites pas, les répertoires appelés 'tsvn', '1svn', 'asvn' etc. seront également ignorés depuis '.' est un caractère générique d'expression rationnelle: "correspondre à n'importe quel caractère".
vladr

D'accord, je pensais que cela ne se produirait que pour les cas de -E et -G. Je viens de tester, ma mauvaise. :(
yclian

2
J'aime cette réponse car elle est conceptuellement plus simple que toutes les autres. Je ne me souviens pas de la syntaxe ridicule pour l'utilisation de «trouver», mais je peux certainement me rappeler comment utiliser grep -v car il est utilisé dans de très nombreuses situations.
mattismyname

8

Créez un script appelé ~/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

Ce script se comporte de manière identique à une findcommande ordinaire mais il élague les .svnrépertoires. Sinon, le comportement est identique.

Exemple:

# 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;

Ce script ne fonctionne pas comme je m'y attendais. Lorsqu'il est exécuté avec "svnfind -type f", il imprime également les répertoires svn et les fichiers dans les répertoires svn
Ingo Fischer

@ifischer Pouvez-vous ajouter un echoà la commande find et me dire quelle commande est exécutée? svnfind -type ffonctionne très bien sur ma machine Red Hat.
John Kugelman

Ok, il semble donc dépendre du système d'exploitation. J'utilise Debian Squeeze (c'est la même chose sur Ubuntu). Je ne comprends pas ce que vous entendez par "ajouter un écho"?
Ingo Fischer

@ifischer Modifiez la dernière ligne pour echo find "${OPTIONS[@]}"...qu'elle imprime la commande find au lieu de l'exécuter.
John Kugelman

Ok a changé la dernière ligne en echo find ${OPTIONS[@]} ${PATHS[@]} -name .svn -type d -prune -o ( ${EXPR[@]} ) $ACTION, Cela me donne la sortie suivante:find -type f -name .svn -type d -prune -o ( -true ) -print
Ingo Fischer

5

Je pensais juste ajouter une alternative simple à de Kaleb et les messages des autres (qui expose en détail l'utilisation de l' find -pruneoption ack, des repofindcommandes , etc.) qui est particulièrement applicable à l'utilisation que vous avez décrite dans la question (et toutes les autres usages similaires):

  1. Pour des performances, vous devez toujours essayer d'utiliser find ... -exec grep ... + (merci Kenji pour l'avoir signalé) ou find ... | xargs egrep ...(portable) ou find ... -print0 | xargs -0 egrep ...(GNU; fonctionne sur les noms de fichiers contenant des espaces) au lieu de find ... -exec grep ... \;.

    le find ... -exec ... +find | xargs formulaire et ne se déroule pas egreppour chaque fichier, mais plutôt pour un groupe de fichiers à la fois, ce qui entraîne une exécution beaucoup plus rapide .

  2. Lorsque vous utilisez le find | xargs formulaire, vous pouvez également utiliser greppour tailler facilement et rapidement .svn(ou tout répertoire ou expression régulière), c'est-à-dire find ... -print0 | grep -v '/\.svn' | xargs -0 egrep ...(utile lorsque vous avez besoin de quelque chose de rapide et que vous ne pouvez pas vous soucier de savoir comment configurer findla -prunelogique.)

    L' find | grep | xargsapproche est similaire à findl' -regexoption de GNU (voir ghostdog74l'article), mais est plus portable (fonctionnera également sur les plates-formes où GNU findn'est pas disponible.)


1
@Vlad: Veuillez noter qu'il existe deux formes pour le -execchangement find: l'une se termine par ;et l'autre se termine par +. Celui qui se termine par +remplace {}par une liste de tous les fichiers correspondants. En outre, votre expression régulière '/\.svn'correspond également aux noms de fichiers '.svn.txt'. Veuillez vous référer à mes commentaires sur la question pour plus d'informations.
Siu Ching Pong -Asuka Kenji-

2
@Vlad: Voici la norme POSIX pour l' findutilitaire. Veuillez consulter la -execpartie :-).
Siu Ching Pong -Asuka Kenji-

4

Dans un référentiel de code source, je veux généralement faire des choses uniquement avec les fichiers texte.

La première ligne comprend tous les fichiers, à l'exception des fichiers de référentiel CVS, SVN et GIT.

La deuxième ligne exclut tous les fichiers binaires.

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

3

J'utilise find avec les options -not -path. Je n'ai pas eu de chance avec le pruneau.

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

trouvera les fichiers groovy pas dans le chemin du répertoire cible.


3

Pour résoudre ce problème, vous pouvez simplement utiliser cette condition de recherche:

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

Vous pouvez ajouter plus de restrictions comme ceci:

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

Vous pouvez trouver plus d'informations à ce sujet dans la section de la page de manuel "Opérateurs": http://unixhelp.ed.ac.uk/CGI/man-cgi?find


3

Notez que si vous le faites

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

-printest alors implicite lorsque toute l'expression ( -type f -name 'messages.*') est vraie, car il n'y a pas d '«action» (comme-exec ).

Tandis que, pour arrêter de descendre dans certains répertoires, vous devez utiliser tout ce qui correspond à ces répertoires et le suivre -prune(qui est destiné à arrêter la descente dans les répertoires); ainsi:

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

Cela équivaut à True pour les répertoires .svn, et nous pouvons utiliser un court-circuit booléen en suivant ceci par -o(OR), après quoi ce qui suit après le -on'est vérifié que lorsque la première partie est False, il ne s'agit donc pas d' un répertoire .svn. En d'autres termes, ce qui suit:

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

ne fera que evalute ce qui est juste de -o, à savoir-name 'message.*' -exec grep -Iw uint {} , pour les fichiers NON à l'intérieur des répertoires .svn.

Notez que parce qu'il .svns'agit probablement toujours d'un répertoire (et non par exemple d'un fichier), et dans ce cas ne correspond certainement pas au nom 'message. *', Vous pouvez aussi bien laisser de côté le -type det faire:

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

Enfin, notez que si vous omettez une action ( -execest une action), dites comme ceci:

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

alors l' -printaction est implicite mais s'appliquera à l'expression WHOLE, y compris la -name '.svn' -prune -opartie et affichera ainsi tous les répertoires .svn ainsi que les fichiers 'message. *', ce qui n'est probablement pas ce que vous voulez. Par conséquent, vous devez toujours utiliser une «action» dans le côté droit de l'expression booléenne lorsque vous utilisez -prunede cette manière. Et lorsque cette action s'imprime, vous devez l'ajouter explicitement, comme ceci:

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


2

Essayez findrepo qui est un simple wrapper autour de find / grep et beaucoup plus rapide que ack Vous l'utiliseriez dans ce cas comme:

findrepo uint 'messages.*'

2

wcfind est un script de wrapper de recherche que j'utilise pour supprimer automatiquement les répertoires .svn.


1

Cela fonctionne pour moi dans l'invite Unix

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

La commande ci-dessus listera les FICHIERS qui ne sont pas avec .svn et fera le grep que vous avez mentionné.


'gfind' est-il une faute de frappe? Je ne l'ai pas sur Ubuntu 14.04.
Jonathan Hartley

En supposant que vous vouliez dire «trouver», cela ne fonctionne pas vraiment. Il filtre également les fichiers comme xxx.svnxxx. C'est important - par exemple, si vous utilisez git au lieu de svn, vous souhaiterez souvent inclure des fichiers comme .gitignore (qui ne sont pas des métadonnées, c'est un fichier normal qui est inclus dans le repo) dans les résultats de find.
Jonathan Hartley

1

Je dirige généralement la sortie via grep une fois de plus en supprimant .svn, dans mon utilisation, ce n'est pas beaucoup plus lent. exemple typique:

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

OU

find . -type f -print0 | xargs -0 egrep messages. | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'

0

Si vous dites à find de rechercher dans '*', alors il sautera tous les "fichiers dot" à la racine:

find *

ou avec chemin

find /path/*

Ce n'est pas une solution exacte / parfaite à la question. Cependant, peu de solutions sont plus simples que celle-ci. Les performances sont également excellentes, car elles n'entrent même pas dans les répertoires cachés.

lacunes:

  • il ne gère pas les "fichiers dot" imbriqués.
  • tous les "fichiers dot" sont ignorés, pas seulement ".git" et ".svn".

Donc, dans votre exemple, l'ajout d'une étoile est la seule modification dont vous auriez besoin:

find * -name 'messages.*' -exec grep -Iw uint {} +
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.