2012-10-19 9 views
6

ich derzeitMit Regex in find-Befehl für mehrere Dateitypen

find . -name '*.[cCHh][cC]' -exec grep -nHr "$1" {} ; \ 
find . -name '*.[cCHh]' -exec grep -nHr "$1" {} ; 

bin mit für eine Zeichenfolge in allen Dateien mit .c, .C, .h, .H, .cc und .CC Endung suchen aufgelistet in allen Unterverzeichnissen. Da dies jedoch zwei Befehle beinhaltet, fühlt sich das ineffizient an.

Wie kann ich ein einzelnes Regex-Muster verwenden, um .c, .C, .h, .H, .cc und .CC Dateien zu finden?

Ich benutze Bash auf einer Linux-Maschine.

+2

BTW, das Argument zu '-name' ist keine Regex, es ist eine Shell-Erweiterung. – rid

Antwort

14

Sie den Booleschen OR Argument verwenden:

find -name '*.[ch]' -o -name '*.[CH]' -o -name '*.cc' -o -name '*.CC' 

Die Dateien, die oben findet, die in Ende:

  • .c, .h ODER
  • .C, .H ODER
  • .cc OR
  • .CC.
+3

Viel eleganter als zu versuchen, alles mit Regexes zu tun. –

+0

Dies funktioniert nicht, wenn Sie "-exec" hinzufügen möchten. Zum Beispiel "find -name \ *. Log '-o -name \ *. Txt -exec cat' {} '\;" Es führt nur den ersten-Namen – OutputLogic

+0

aus, wenn Sie aus irgendeinem Grund nicht erkennen, ist '- o' – Crowie

0

find . -regex '.*\.\([chCH]\|cc\|CC\)'
werden alle Dateien mit Namen mit der Endung .c finden, .C, .h, .H, .cc und .CC und finden keinen, dass Ende in .hc, .CC oder. Cc. In der Regex stimmen die ersten paar Zeichen mit der letzten Periode in einem Namen überein, und die eingeklammerten Alternativen entsprechen einem der einzelnen Zeichen c, h, C oder H oder entweder cc oder CC.

Hinweis, finden die -regex und -iregex Schalter sind analog zu -name und -iname, aber die regex-Typ Schalter ermöglichen reguläre Ausdrücke mit | für alternative Übereinstimmungen. Wie -iname, -iregex ist case-insensitive.

Die (nicht funktionsfähig) Form
find . -name '*.[cCHh][cC]?$'
in einer früheren Antwort gegeben Liste keine Namen auf meinem Linux-System mit GNU 4.4.2 finden. Ein weiteres Problem mit '*.[cCHh][cC]?$' als Regex ist, dass es Namen wie abc.Cc und xyz.hc, die nicht in der Menge der gewünschten .c, .c, .h, .h, .cc und .CC-Dateien sind.

+0

die erste Form funktioniert nicht, weil '?' Und '$' keine Shell-Muster sind, so dass sie wörtlich interpretiert werden – doubleDown

+0

@rid, ich bearbeitet, um darauf hinzuweisen, dass '-iregex'. * \. [Ch] \ |. * \ .cc'' passt * nicht * .cH. Ich stimme jedoch zu, dass es mit .Cc und .cC übereinstimmt und ein '-regex für den exakten Satz von Erweiterungen hinzugefügt hat –

11

Messy

find . -iregex '.*\.\(c\|cc\|h\)' -exec grep -nHr "$1" {} ; 

-iregex für Groß- und Kleinschreibung RegexMuster arbeiten Dies sollte.

(c|cc|h) (böse entkommt nicht gezeigt) übereinstimmt c, cc oder h Erweiterungen


reinigen

find -regextype "posix-extended" -iregex '.*\.(c|cc|h)' -exec grep -nHr "$1" {} ; 

Dies finden .CC und.cC Erweiterungen auch. Du wurdest gewarnt.

1

Dieser Befehl funktioniert.

find -regextype posix-extended -regex '.+\.(h|H|c{1,2}|C{1,2})$' 

Ich wünschte, ich könnte iregex verwenden. iregex würde auch .Cc und .cC finden. Wenn ich könnte, würde der Befehl so aussehen. Nur ein bisschen kürzer.

find -regextype posix-extended -iregex '.+\.(h|H|c{1,2})$' 
Verwandte Themen