Wie kann ich "find" dazu bringen, .svn-Verzeichnisse zu ignorieren?


227

Ich benutze den findBefehl oft, um den Quellcode zu durchsuchen, Dateien zu löschen, was auch immer. Ärgerlicherweise, weil Subversion Duplikate jeder Datei in seinen .svn/text-base/Verzeichnissen speichert, erhalten meine einfachen Suchvorgänge viele doppelte Ergebnisse. Zum Beispiel möchte ich rekursiv uintin mehreren messages.hund messages.cppDateien suchen :

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

Wie kann ich sagen find, dass die .svnVerzeichnisse ignoriert werden sollen ?


Update : Wenn Sie Ihren SVN-Client auf Version 1.7 aktualisieren, ist dies kein Problem mehr.

Ein wesentliches Merkmal der in Subversion 1.7 eingeführten Änderungen ist die Zentralisierung des Speichers von Arbeitskopien-Metadaten an einem einzigen Speicherort. Anstelle eines .svnVerzeichnisses in jedem Verzeichnis in der Arbeitskopie haben Subversion 1.7-Arbeitskopien nur ein .svnVerzeichnis - im Stammverzeichnis der Arbeitskopie. Dieses Verzeichnis enthält (unter anderem) eine SQLite-gestützte Datenbank, die alle Metadaten enthält, die Subversion für diese Arbeitskopie benötigt.


4
Versuchen Sie für die Leistung, find ... -print0 | xargs -0 egrep ...anstelle von zu verwenden find ... -exec grep ...(nicht grepfür jede Datei, sondern für mehrere Dateien gleichzeitig). Mit diesem Formular können Sie auch .svnVerzeichnisse -prunefind ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...
bereinigen,

3
@Vlad: Soweit ich weiß, mit -execmit +Gabel nicht grepfür jede Datei, während es bei der Verwendung des ;Fall ist. Verwenden -execist eigentlich korrekter als Verwenden xargs. Bitte beachten Sie, dass Befehle wie " lsetwas tun", auch wenn die Argumentliste leer ist, während Befehle wie " chmodFehler" geben, wenn nicht genügend Argumente vorhanden sind. Um zu sehen, was ich meine, versuchen Sie einfach den folgenden Befehl in einem Verzeichnis, das kein Shell-Skript enthält : find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755. Vergleichen Sie mit diesem : find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'.
Siu Ching Pong -Asuka Kenji-

2
@Vlad: Außerdem grep-ing out .svnist auch keine gute Idee. Während findes auf die Behandlung von Dateieigenschaften spezialisiert ist, ist grepdies nicht der Fall. In Ihrem Beispiel wird eine Datei mit dem Namen '.svn.txt' ebenfalls von Ihrem egrepBefehl gefiltert . Obwohl Sie Ihren regulären Ausdruck in '^ / \. Svn $' ändern können , ist dies immer noch keine gute Vorgehensweise. Das -prunePrädikat von findeignet sich perfekt zum Filtern einer Datei (nach Dateiname, Erstellungszeitstempel oder der von Ihnen angegebenen Bedingung). Es ist so, als ob selbst wenn man eine Kakerlake mit einem großen Schwert töten kann, dies nicht bedeutet, dass dies der vorgeschlagene Weg ist :-).
Siu Ching Pong -Asuka Kenji-

3
Durch den Wechsel zu Git wurde dieses Problem behoben (unter anderem). In erstellt nur einen .git-Ordner im Stammverzeichnis der Arbeitskopie, nicht in jedem Ordner davon wie SVN. Darüber hinaus enthält der Ordner .git keine einfachen Dateien, die mit Ihren tatsächlichen Dateien mit demselben Namen verwechselt würden.
Tronic

3
2Dan Moulding: SVN 1.7 erstellt nur ein einziges Top-Level-SVN-Verzeichnis
ccpizza

Antworten:


65

Kann ich Ihnen für die Suche vorschlagen, sich ack anzuschauen ? Es ist ein Quellcode-fähig findund ignoriert daher automatisch viele Dateitypen, einschließlich Quellcode-Repository-Informationen wie die oben genannten.


3
Ich mag es acksehr, aber ich habe festgestellt, dass es wesentlich langsamer ist als find -type f -name "*.[ch]" | xargs grepbeim Umgang mit einer großen Codebasis.
John Ledbetter

63
John, ich bin der Autor von ack, und wenn Sie mir Einzelheiten zu den Geschwindigkeitsproblemen von ack vs. grep geben können, würde ich es begrüßen. Sie waren in allen Fällen, die ich gefunden habe, völlig vergleichbar. Lassen Sie es mich entweder unter github.com/petdance/ack/issues wissen oder senden Sie mir eine E-Mail an andy unter petdance.com. Thansk.
Andy Lester

63
Leute, das ist ein Tipp, aber definitiv keine Antwort auf die Frage! :)
Dolzenko

8
Wird nicht ackals besser grep, nicht quellenbewusst abgerechnet find? Einige Beispiele für die Verwendung als Ersatz findwürden dies zu einer echten Antwort machen.
michiakig

3
Es ist eine Antwort auf die Frage, von der er nicht wusste, dass er sie stellte. =)
Frungi

293

warum nicht einfach

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

Das Prädikat -not negiert alles, was irgendwo im Pfad .svn hat.

In Ihrem Fall wäre es also so

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

5
Super groß +1 für "-not" und "-iwholename". Ack ist wunderbar und ich benutze es, aber find / exec hat immer noch seine Verwendung.
David Blevins

9
Die einzige Antwort, die die ursprüngliche Frage tatsächlich beantwortet hat.
Brendon Crawford

14
Ich bin weit weg von meinem Element und ich bin sicher, dass ich für diesen Kommentar kritisiert werde, aber anscheinend sind -not und -wholename nicht POSIX-konform. Ich benutzte ! anstelle von -not und -path anstelle von -iwholename und erzielte die gleichen Ergebnisse. Laut meinen Manpages (Ubuntu 12.04) ist diese Syntax POSIX-kompatibel.
John

1
@waley Du hast '*.svn*'zuerst aber dann gesagt '*.svn'. Welches ist richtig? Arbeiten beide? Ich denke es sollte wohl sein '*.svn*'?
Keith M

1
@KeithM toller Fang eigentlich. Diese Antwort sitzt seit Jahren hier und ich glaube, bis jetzt hat das noch niemand mitbekommen.
Whaley

141

Wie folgt:

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

Oder alternativ basierend auf einem Verzeichnis und nicht auf einem Pfadpräfix:

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

14
@ Kaleb: Hallo. Ich schlage vor, find . -type d -name .svn -prune -o -printweil es etwas schneller ist. Gemäß dem POSIX-Standard werden die Ausdrücke einzeln in der angegebenen Reihenfolge ausgewertet. Wenn der erste Ausdruck in -aist false, wird der zweite Ausdruck nicht ausgewertet (auch Kurzschluss und Auswertung genannt ).
Siu Ching Pong -Asuka Kenji-

2
@Kaleb: Als Vergleich den Dateitypen (äquivalent zu testen , ob ein Bit in einer ganzen Zahl eingestellt ist) ist , schneller als Vergleich den Dateinamen (äquivalent zu einem String - Vergleich, die O (n)), setzt , -type dbevor -name .svntheoretisch effizienter. Es ist jedoch normalerweise unbedeutend, außer wenn Sie einen sehr sehr großen Verzeichnisbaum haben.
Siu Ching Pong -Asuka Kenji-

5
@ SiuChingPong-AsukaKenji- nein, der Vergleich nur des Dateinamens ist schneller, da -type für jede Datei einen stat (2) -Aufruf erfordert. Der Dateiname ist jedoch Teil der Antwort readdir (3).
Hraban

3
@ JonathanHartley Du vermisst das -printals Teil des letzten Ausdrucks. So etwas find . -name .git -prune -o \( -type f -name LICENSE -print \)funktioniert wie erwartet.
Sschuberth

1
Wenn Sie sowohl .git als auch .svn ignorieren und nur die anderen Verzeichnisse auflisten möchten , find . -name .svn -prune -o -name .git -prune -o -type d -print. Es mag ein paar Millisekunden schneller sein, -type dvor die beiden zu -nametreten, aber die zusätzliche Eingabe lohnt sich nicht.
JPaget

34

Versuchen Sie Folgendes .svn, um .gitandere versteckte Verzeichnisse (beginnend mit einem Punkt) zu ignorieren :

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

Wenn der Verwendungszweck jedoch darin findbesteht, in den Dateien zu suchen, können Sie versuchen, die folgenden Befehle zu verwenden:

  • git grep - Speziell entwickelter Befehl zum Suchen von Mustern im Git-Repository.
  • ripgrep- die standardmäßig versteckte Dateien und Dateien ignoriert, die in angegeben sind .gitignore.

Verwandte: Wie finde ich alle Dateien, die bestimmten Text enthalten, unter Linux?


Beste Antwort imo. Die anderen versuchen Dinge zu erklären, die die einfache Frage nicht beantworten.
Anthony

19

Folgendes würde ich in Ihrem Fall tun:

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

Der in Emacs rgrepintegrierte Befehl ignoriert das .svnVerzeichnis und viele weitere Dateien, an denen Sie wahrscheinlich nicht interessiert sind, wenn Sie eine ausführen find | grep. Folgendes wird standardmäßig verwendet:

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

Verzeichnisse, die von den meisten Versionskontrollsystemen erstellt wurden, sowie generierte Dateien für viele Programmiersprachen werden ignoriert. Sie können einen Alias ​​erstellen, der diesen Befehl aufruft findund grepMuster für Ihre spezifischen Probleme ersetzt.


12

GNU finden

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

Ich habe die Verzeichnispfade in ein Array geladen, damit PHP sie verarbeiten kann. Die anderen Antworten weiter oben (aus welchem ​​Grund auch immer) haben die Dateien im Fund (trotz der -type d) nicht herausgefiltert - diese Antwort hat es getan. +1
sei hollenbeck

11

Ich benutze grep für diesen Zweck. Tragen Sie dies in Ihr ~ / .bashrc ein

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

grep verwendet diese Optionen beim Aufruf automatisch


1
Es ist erwähnenswert, dass 'grep' erst vor ein oder zwei Jahren die Option '--exclude-dir' erhalten hat. Neuere Linux-Distributionen enthalten es, aber wenn ich mich richtig erinnere, musste ich mein eigenes grep unter OSX kompilieren (oder Homebrew darum bitten).
Jonathan Hartley

Ich benutze eine kleine Variante davon. Meine .bashrc erstellt eine Bash-Funktion 'grp', die definiert ist als GREP_OPTIONS=xxx grep "$@". Dies bedeutet, dass die Variable GREP_OPTIONS nur für Instanzen von grep festgelegt ist, die ich manuell mit 'grp' ausführe. Dies bedeutet, dass ich nie eine Situation bekomme, in der ich ein Tool ausführe, und intern ruft es grep auf, aber das Tool wird verwirrt, weil grep sich nicht wie erwartet verhält. Außerdem habe ich eine zweite Funktion 'grpy', die 'grp' aufruft, aber hinzufügt --include=*.py, um nur Python-Dateien zu durchsuchen.
Jonathan Hartley

Eigentlich muss GREP_OPTIONS nach meiner Überlegung überhaupt nicht mehr verwendet werden. Ich habe jetzt nur eine Shell-Funktion 'grp', die aufruft grep --exclude=tags --exclude_dir=.git ...etc... "$@". Ich mag es, dass dies wie "ack" läuft, aber ich behalte das Bewusstsein und die Kontrolle darüber, was es tut.
Jonathan Hartley

9

find . | grep -v \.svn


Sie müssen .im .svnregulären Ausdruck entkommen .
Vladr

4
Verwenden Sie --fixed-strings mit grep: | fgrep -v /.svn/oder `| grep -F -v / .svn / `, um genau das Verzeichnis auszuschließen und keine Dateien mit" .svn "als Teil ihres Namens.
Stephen P

8

Warum leiten Sie Ihren Befehl nicht mit grep weiter, was leicht verständlich ist:

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

Sie müssen .im .svnregulären Ausdruck entkommen .
Vladr

@ Yclian ohne den Schatten eines Zweifels; Wenn Sie dies nicht tun, werden Verzeichnisse mit den Namen 'tsvn', '1svn', 'asvn' usw. ebenfalls ignoriert, da '.' ist ein Regexp-Platzhalter: 'Mit einem beliebigen Zeichen übereinstimmen'.
Vladr

Okay, ich dachte, das würde nur für den Fall von -E und -G passieren. Ich habe gerade getestet, mein schlechtes. :(
Yclian

2
Ich mag diese Antwort, weil sie konzeptionell einfacher ist als alle anderen. Ich kann mich nicht an die lächerliche Syntax für die Verwendung von 'find' erinnern, aber ich kann mich definitiv daran erinnern, wie man grep -v verwendet, da es in sehr vielen Situationen verwendet wird.
Mattismyname

8

Erstellen Sie ein Skript mit dem Namen ~/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

Dieses Skript verhält sich identisch mit einem einfachen findBefehl, wird jedoch entfernt.svn Verzeichnisse. Ansonsten ist das Verhalten identisch.

Beispiel:

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

Dieses Skript funktioniert nicht wie erwartet. Wenn es mit "svnfind -type f" ausgeführt wird, werden auch SVN-Verzeichnisse und die Dateien in den SVN-Verzeichnissen gedruckt
Ingo Fischer

@ifischer Kannst du echodem Befehl find ein hinzufügen und mir sagen, welcher Befehl ausgeführt wird? svnfind -type ffunktioniert hervorragend auf meinem Red Hat-Computer.
John Kugelman

Ok, es scheint also vom Betriebssystem abhängig zu sein. Ich verwende Debian Squeeze (unter Ubuntu ist es dasselbe). Ich verstehe nicht, was Sie unter "Echo hinzufügen" verstehen?
Ingo Fischer

@ifischer Ändern Sie die letzte Zeile in, echo find "${OPTIONS[@]}"...damit der Befehl find gedruckt wird, anstatt ihn tatsächlich auszuführen .
John Kugelman

Ok änderte die letzte Zeile in echo find ${OPTIONS[@]} ${PATHS[@]} -name .svn -type d -prune -o ( ${EXPR[@]} ) $ACTION, Dies gibt mir die folgende Ausgabe:find -type f -name .svn -type d -prune -o ( -true ) -print
Ingo Fischer

5

Ich dachte , ich hinzufügen würde eine einfache Alternative zu Kaleb ist und Beiträge anderer (die die Verwendung der detaillierten find -pruneOption ack, repofindBefehle usw.), die auf die Verwendung besonders für Sie in der Frage beschriebenen (und jede andere ähnliche Verwendungen):

  1. Für die Leistung sollten Sie immer versuchen, find ... -exec grep ... +(danke Kenji für den Hinweis) oder find ... | xargs egrep ...(portabel) oder find ... -print0 | xargs -0 egrep ...(GNU; arbeitet mit Dateinamen, die Leerzeichen enthalten) anstelle von zu verwenden find ... -exec grep ... \;.

    Das find ... -exec ... +und find | xargs-Formular teilt sich nicht egrepfür jede Datei, sondern für eine Reihe von Dateien gleichzeitig, was zu einer viel schnelleren Ausführung führt .

  2. Bei Verwendung des find | xargsFormulars können Sie auch verwenden , grepum einfach und schnell Pflaume .svn(oder alle Verzeichnisse oder ein regulärer Ausdruck), dh find ... -print0 | grep -v '/\.svn' | xargs -0 egrep ...(nützlich , wenn Sie etwas schnell brauchen , und nicht gestört werden können , um daran erinnern , wie einzurichten find‚s -pruneLogik.)

    Der find | grep | xargsAnsatz ähnelt GNU find‚s - -regexOption (siehe ghostdog74‘ s post), ist aber mehr tragbar (funktioniert auch auf Plattformen , auf denen GNU findist nicht verfügbar.)


1
@Vlad: Bitte beachten Sie, dass es zwei Formen für den -execWechsel gibt find: eine endet mit ;und die andere endet mit +. Der eine mit der Endung +ersetzt {}durch eine Liste aller passenden Dateien. Außerdem '/\.svn'stimmt Ihre Regex auch mit Dateinamen überein '.svn.txt'. Weitere Informationen finden Sie in meinen Kommentaren zur Frage.
Siu Ching Pong -Asuka Kenji-

2
@Vlad: Hier ist der POSIX-Standard für das findDienstprogramm. Bitte beachten Sie den -execTeil :-).
Siu Ching Pong -Asuka Kenji-

4

In einem Quellcode-Repository möchte ich im Allgemeinen nur die Textdateien bearbeiten.

Die erste Zeile enthält alle Dateien mit Ausnahme der CVS-, SVN- und GIT-Repository-Dateien.

Die zweite Zeile schließt alle Binärdateien aus.

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

Ich benutze find mit den Optionen -not -path. Ich hatte kein Glück mit Pflaumen.

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

findet die groovigen Dateien nicht im Zielverzeichnispfad.


3

Um dieses Problem zu beheben, können Sie einfach diese Suchbedingung verwenden:

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

Sie können weitere Einschränkungen wie folgt hinzufügen:

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

Weitere Informationen hierzu finden Sie im Manpage-Abschnitt "Operatoren": http://unixhelp.ed.ac.uk/CGI/man-cgi?find


3

Beachten Sie dies, wenn Sie dies tun

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

dann -printwird impliziert, wenn der gesamte Ausdruck ( -type f -name 'messages.*') wahr ist, weil es keine 'Aktion' (wie -exec) gibt.

Um den Abstieg in bestimmte Verzeichnisse zu beenden, sollten Sie alles verwenden, was mit diesen Verzeichnissen übereinstimmt, und ihm folgen -prune(was den Abstieg in Verzeichnisse beenden soll). wie so:

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

Dies wird für die .svn-Verzeichnisse als True ausgewertet , und wir können einen booleschen Kurzschluss verwenden, indem wir diesem durch -o(OR) folgen. Danach wird das, was nach dem -ofolgt, nur überprüft, wenn der erste Teil False ist, und ist daher kein .svn-Verzeichnis. Mit anderen Worten:

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

wird nur bewerten, was richtig ist -o, nämlich -name 'message.*' -exec grep -Iw uint {}für Dateien, die sich NICHT in .svn-Verzeichnissen befinden.

Beachten Sie, dass Sie, da .svnes sich wahrscheinlich immer um ein Verzeichnis handelt (und nicht zum Beispiel um eine Datei) und in diesem Fall sicherlich nicht mit dem Namen 'message. *' Übereinstimmt, das -type dund auch tun können:

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

Beachten Sie schließlich, dass Sie, wenn Sie eine Aktion auslassen ( -execeine Aktion ist), wie folgt sagen:

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

Dann wird die -printAktion impliziert, gilt jedoch für den GANZEN Ausdruck, einschließlich des -name '.svn' -prune -oTeils, und druckt somit alle .svn-Verzeichnisse sowie die 'message. *' - Dateien, was wahrscheinlich nicht das ist, was Sie wollen. Daher sollten Sie auf diese Weise immer eine 'Aktion' auf der rechten Seite des booleschen Ausdrucks verwenden -prune. Und wenn diese Aktion gedruckt wird, müssen Sie sie explizit hinzufügen, wie folgt:

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


2

Versuchen Sie es mit findrepo , einem einfachen Wrapper um find / grep und viel schneller als ack. Sie würden es in diesem Fall wie folgt verwenden:

findrepo uint 'messages.*'

2

wcfind ist ein Find-Wrapper-Skript, mit dem ich .svn-Verzeichnisse automatisch entferne.


1

Dies funktioniert bei mir in der Unix-Eingabeaufforderung

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

Mit dem obigen Befehl werden DATEIEN aufgelistet, die nicht mit .svn verknüpft sind, und der von Ihnen erwähnte grep ausgeführt.


ist 'gfind' ein Tippfehler? Ich habe es nicht auf Ubuntu 14.04.
Jonathan Hartley

Angenommen, Sie meinten "finden", funktioniert dies nicht ganz. Es filtert auch Dateien wie xxx.svnxxx. Dies ist wichtig. Wenn Sie beispielsweise git anstelle von svn verwenden, möchten Sie häufig Dateien wie .gitignore (keine Metadaten, sondern eine reguläre Datei, die im Repo enthalten ist) in die Ergebnisse von find aufnehmen.
Jonathan Hartley

1

Normalerweise leite ich die Ausgabe noch einmal durch grep und entferne .svn. Bei meiner Verwendung ist sie nicht viel langsamer. typisches Beispiel:

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

ODER

find . -type f -print0 | xargs -0 egrep messages. | grep -Ev '.svn|.git|.anythingElseIwannaIgnore'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.