2012-05-16 11 views
62

Quando voglio grep tutti i file HTML in una directory, faccio la seguentecome utilizzare l'opzione grep - include per più tipi di file?

grep --include="*.html" pattern -R /some/path

che funziona bene. Il problema è come grep tutti i file html, htm, php in qualche directory?

Da questo Use grep --exclude/--include syntax to not grep through certain files, sembra che io possa fare la seguente

grep --include="*.{html,php,htm}" pattern -R /some/path

Ma, purtroppo, che non avrebbe funzionato per me.
FYI, la mia versione di grep è 2.5.1.

risposta

90

È possibile utilizzare più flag --include. Questo funziona per me:

grep -r --include=*.html --include=*.php --include=*.htm "pattern" /some/path/

Tuttavia, si può fare come Deruijter suggerito. Questo funziona per me:

grep -r --include=*.{html,php,htm} "pattern" /some/path/

Non dimenticate che è possibile utilizzare find e xargs per questo genere di cose a:

find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"

HTH

+1

Vedo il problema. Ho usato --include = "*. {Html, php}" per impedire alla shell di espandere '*' che allo stesso tempo interrompe la shell per espandere {html, php}. Sembra che il segno di uguale in --include = * sia in grado di impedire alla shell di espandere '*'. – tianyapiaozi

+0

xargs non è davvero un sostituto; molte volte quando hai bisogno di questa funzione, hai a che fare con più file di quelli gestiti da xargs. –

+2

@JamesMoore: date un'occhiata a [GNU Parallel] (https://www.gnu.org/software/parallel/). Può spesso essere usato come sostituto di 'xargs'. [Questo] (https://www.gnu.org/software/parallel/man.html#differences_between_xargs_and_gnu_parallel) vale anche una lettura veloce. HTH. – Steve

4

non funziona?

grep pattern /some/path/*.{html,php,htm} 
+0

Non proprio. I file possono risiedere nella sottodirectory della sottodirectory – tianyapiaozi

9

provare a rimuovere le virgolette

grep --include=*.{html,php,htm} pattern -R /some/path 
+0

non funziona neanche. – tianyapiaozi

+0

@tianyapiaozi Prova 'grep --include = \ *. {Html, php, htm} pattern -R/some/path'. Ha funzionato per me. –

0

Utilizzare grep con find comando

find /some/path -name '*.html' -o -name '*.htm' -o -name '*.php' -type f 
-exec grep PATTERN {} \+ 

È possibile utilizzare -regex e -regextype opzioni troppo.

2

Prova questo. -r eseguirà una ricerca ricorsiva. -s sopprimerà gli errori di file non trovati. -n mostrerà il numero di riga del file in cui è stato trovato il modello.

grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h} 
+0

Questa è la risposta migliore per me in particolare, e penso che tu possa mettere -rsn al posto di -r -s -n (ma questo è il pignolo). – slim

+0

Solitamente utilizzo ** - rns **. Per chiarezza nell'esempio ho dovuto menzionare ** - r -n -s ** :-) Sono contento che sia stato d'aiuto. – Pradeep

8

Uso {html,php,htm} può funzionare solo come brace expansion, che è una caratteristica non standard (non POSIX) di bash, ksh e zsh.

  • In altre parole: non cercate di usarlo in uno script che gli obiettivi /bin/sh - utilizzare esplicito multipli --include argomenti in quel caso.

  • grepnon capire {...} notazione.

Per un'espansione tutore per essere riconosciuto, è deve essere un unquoted (parte di) gettone sulla linea di comando.

Un'espansione delle parentesi graffe espande a più argomenti, così nel caso in esame grep finisce per vedere multipla--include=... opzioni, proprio come se fossero stati passati singolarmente.

I risultati di un'espansione delle graffe sono soggette a globbing (espansione dei nomi), che ha insidie ​​:

  • Ogni argomento risultante potrebbe essere ulteriormente espansa per corrispondenza nomi se succede a contenere non quotati metacaratteri globbing come *.
    Anche se è improbabile con token come --include=*.html (ad es. Dovresti avere un file chiamato letteralmente qualcosa come --include=foo.html per qualcosa che corrisponde), vale la pena tenerlo a mente in generale.

  • Se l'opzione di shell nullglob sembra essere acceso (shopt -s nullglob) e glob partite nulla, l'argomento sarà scartato .

Pertanto, per una soluzione completamente robusto, utilizzare il seguente:

grep -R '--include=*.'{html,php,htm} pattern /some/path 
  • '--include=*.' è considerato un letterale, a causa di essere apici singoli; questo impedisce interpretazioni involontarie di * come un personaggio globbing.

  • {html,php,htm}, la - necessariamente - unquoted espansione delle graffe [1] , espande per argomenti, che, a causa di {...}direttamente seguenti la '...' gettone, includono quel segno.

  • Pertanto, dopo la rimozione citazione dalla shell, seguente letterali argomenti vengono infine trasferiti alla grep:

    • --include=*.html
    • --include=*.php
    • --include=*.htm

[1] Più precisamente, è solo sintassi rilevanti parti dell'espansione tutore che deve essere non quotate, i elementi dell'elenco potrebbero ancora essere citati singolarmente e devono essere se contengono metacaratteri globbing che potrebbero causare globbing indesiderati dopo l'espansione brace; anche se non necessario in questo caso, quanto sopra potrebbe essere scritto come
'--include=*.'{'html','php','htm'}

+1

Grazie mille per questo post. I post fantastici non solo rispondono alla domanda, ma ti insegnano qualcosa di nuovo! Ciò è particolarmente utile per quelli di noi che scrivono su qualcosa che deve essere conforme a POSIX. Chiunque usi Mac OS X dovrebbe guardare qui! – sabalaba

+0

@sabalaba: Sono lieto di sentirlo, ma per essere chiari: mentre l'espansione delle parentesi non è conforme a POSIX, funziona con 'bash' su qualsiasi piattaforma su cui gira' bash'. – mklement0