2012-10-19 9 views
6

Attualmente sto usandoUtilizzando regex nel comando find per più tipi di file

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

per la ricerca di una stringa in tutti i file che terminano con .c, .C, .h, .H, .cc e .CC elencato in tutte le sottodirectory. Ma dal momento che questo include due comandi, questo sembra inefficiente.

Come è possibile utilizzare un modello di regex singolo per trovare file .c, .C, .h, .H, .cc e .CC?

Sto usando bash su una macchina Linux.

+2

BTW, l'argomento di '-name' non è un'espressione regolare, è un'espansione della shell. – rid

risposta

14

È possibile utilizzare l'argomento booleano OR:

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

Quanto sopra trova i file che terminano in:

  • .c, .h O
  • .C, .H O
  • .cc O
  • .CC.
+3

Molto più elegante di provare a fare tutto con espressioni regex. –

+0

Questo non funziona se si desidera aggiungere "-exec". Ad esempio "find -name \ *. Log '-o -name \ *. Txt -exec cat' {} '\;" Esegue solo il primo nome – OutputLogic

+0

che se per qualche motivo non ti rendi conto è '- o' – Crowie

0

find . -regex '.*\.\([chCH]\|cc\|CC\)'
troverà tutti i file con i nomi che terminano in .c, .C, .h, .H, .cc e .CC e non trova alcuna tal fine nel .hc, .cc, o. cc. Nella regex, i primi caratteri corrispondono all'ultimo periodo di un nome e le alternative parentesi corrispondono ai singoli caratteri c, h, C o H o a cc o CC.

nota, trovare di -regex e -iregex interruttori sono analoghi a -name e -iname, ma le espressioni regolari di tipo switch permettono le espressioni regolari con | per le partite alternativi. Come -iname, -iregex non fa distinzione tra maiuscole e minuscole.

Il (non funzionale) forma
find . -name '*.[cCHh][cC]?$'
dato in una risposta precedente non elenca tutti i nomi sul mio sistema Linux con GNU trovare 4.4.2. Un altro problema con '*.[cCHh][cC]?$' come espressione regolare è che corrisponderà a nomi come abc.Cc e xyz.hc che non sono nel set di file .c, .C, .h, .H, .cc e .CC che si desidera.

+0

il primo modulo non funziona perché '?' E '$' non sono schemi di shell in modo che siano interpretati letteralmente – doubleDown

+0

@rid, ho modificato per sottolineare che' -iregex '. * \. [Ch] \ |. * \ .cc'' fa * non * corrisponde a .cH. Tuttavia, sono d'accordo che corrisponda a .Cc e .cC e aggiunto un '-regex per il set esatto di estensioni –

11

Questo dovrebbe funzionare

sudicio

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

-iregex testo regex maiuscole e minuscole.

(c|cc|h) (fughe brutto non mostrate) partite c, cc, o h estensioni


Clean

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

Questo troverà .cc e.estensioni cC troppo. Sei stato avvertito.

1

Questo comando funziona.

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

Vorrei poter utilizzare iregex. iregex troverà anche .Cc e .cC. Se potessi, il comando sarebbe simile a questo. Un po 'più breve.

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