grep, ma solo determinate estensioni di file


966

Sto lavorando a scrivere alcuni script per grep determinate directory, ma queste directory contengono tutti i tipi di tipi di file.

Voglio grepsolo .he .cppper ora, ma forse alcuni altri in futuro.

Finora ho:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP email@domain.com

Qualcuno può mostrarmi come ora aggiungerei solo le estensioni di file specifiche?


13
Provato grep -r -i CP_Image ~/path1/*.{h,cpp}?

8
Utilizzare The Silver Searcher : ag -i CP_Image ~/path[1-5] | mailx -s GREP email@domain.com. Lavoro fatto.
Johnsyweb,


Usa egrep (è molto probabilmente preinstallato sul tuo sistema) e quindi puoi usare un regex.
Dogweather,

8
I ragazzi di GNU hanno davvero incasinato quando hanno aggiunto -rdi grepaverlo alla ricerca di file in quanto spezza il mantra UNIX di avere strumenti che "fanno una cosa e la fanno bene". C'è uno strumento perfettamente valido per trovare file con un nome MOLTO ovvio.
Ed Morton,

Risposte:


1354

Basta usare il --includeparametro, in questo modo:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

quello dovrebbe fare quello che vuoi.

Per prendere la spiegazione dalla risposta di HoldOffHunger di seguito:

  • grep: comando

  • -r: ricorsivamente

  • -i: ignore-case

  • --include \*.cpp: all * .cpp: file C ++ (scappa con \ nel caso in cui tu abbia una directory con asterischi nei nomi dei file)

  • ./: Inizia dalla directory corrente.


123
Per la cronaca: -r (ricorsivo) -i (ignora-case) --include (cerca solo i file che corrispondono allo schema dei file)
Luis

34
Può essere ulteriormente ottimizzato pergrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol il

1
@Hong dov'è la documentazione che -R è per i collegamenti simbolici?
Tito

8
Questo esempio sembra avere un punteggio alto perché copre una gamma così ampia di possibilità ma la risposta fornita di seguito di grep -r --include = *. Txt 'searchterm' ./ spiega davvero l'essenza della risposta
David Casper

10
perché non usare le virgolette doppie anziché la barra rovesciata? ad esempio:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda,

283

Alcune di queste risposte sembravano troppo pesanti per la sintassi, o hanno prodotto problemi sul mio server Debian. Ha funzionato perfettamente per me:

Rivoluzione PHP: come Grep file in Linux, ma solo determinate estensioni di file?

Vale a dire:

grep -r --include=\*.txt 'searchterm' ./

... o versione senza distinzione tra maiuscole e minuscole ...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep: comando

  • -r: ricorsivamente

  • -i: ignore-case

  • --include: all * .txt: file di testo (scappa con \ nel caso in cui tu abbia una directory con asterischi nei nomi dei file)

  • 'searchterm': Cosa cercare

  • ./: Inizia dalla directory corrente.


7
Dovresti evitare l' *uso di \*.cppo '*.cpp'. Altrimenti non darà il risultato atteso quando la directory di lavoro contiene alcuni *.txtfile.
Melebio

@Melebius puoi spiegare perché deve essere evaso - ha qualcosa a che fare con le estensioni CPP o TXT che hai citato? O li hai appena usati come esempi?
Simon East,

2
@SimonEast Queste estensioni sono quelle utilizzate in questa domanda e risposta, altrimenti niente di speciale. Probabilmente funzionerebbe senza scappare quando lo si utilizza, --include=<pattern>ma è importante scappare *con --include <pattern>(uno spazio anziché =) che altrimenti sembra molto simile.
Melebio

52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./

3
grep -rn "qualche cosa da grep" --include = *. {module, inc, c, h} *
ashish

3
Bella risposta. Più pulito di quello accettato su IMO ma è necessario aggiungere i criteri di ricerca come notato da @ashish
billynoah

perché l' --includeopzione dopo ago, non con altre opzioni?
Vladkras,

@vladkras, cosa intendi con ago? È vero --?
Heretoinfinity

50

Che ne dite di:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print

5
suggerirei di raggruppare tali -nameargomenti. cose strane possono accadere se non lo fai. find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
nullrevolution

utilizzare con "-type f" aggiuntivo per ignorare tutti gli oggetti directory, interessati solo ai file.
Kensai,

1
Ho usato questo metodo per anni e funziona, ma è MOLTO più lento del grep ricorsivo poiché il exec di find genera un processo grep separato per ogni file da cercare.
beaudet,

Rivolgendosi al commento di @ beaudet, è findpossibile raggruppare facoltativamente argomenti, riducendo al minimo le invocazioni del processo chiamato. find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + Questo è suggerito ma non evidenziato nella risposta di @ fedorqui di seguito ed è un miglioramento utile. L' -Hargomento per grep qui è utile quando find identifica solo un singolo file corrispondente. Ciò potrebbe eliminare l'utilizzo di -printnella risposta. Se l'elenco totale dei file è sufficientemente piccolo, {path1,path2}/**/*.{cpp,h}è preferibile utilizzare un glob shell ricorsivo (ad es. ).
Malcolm,

19

Non esiste alcuna opzione -r sui server HP e Sun, in questo modo ha funzionato per me sul mio server HP

find . -name "*.c" | xargs grep -i "my great text"

-i è per la ricerca senza distinzione tra maiuscole e minuscole della stringa


1
Ho incontrato diversi server per le società di web hosting che non hanno l'opzione --include disponibile per fgrep e questa è la riga di comando che uso in quei casi.
Borgboy,

L'opzione --include non è disponibile anche quando si utilizza Git per Windows (MinGW / MSys).
Darren Lewis

@DarrenLew è disponibile in Git Bash per Windows. Ma stranamente, aggiunge alias colorati come llma non aggiunge--color=auto a grep.
Xeverous,

Questa dovrebbe essere la risposta accettata per completezza, portabilità e brevità!
Grant Foster

12

Dato che si tratta di trovare file, usiamo find!

Usando GNU find puoi usare l' -regexopzione per trovare quei file nell'albero delle directory la cui estensione è o .ho .cpp:

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

Quindi, è solo una questione di esecuzione grepsu ciascuno dei suoi risultati:

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

Se non hai questa distribuzione di find devi usare un approccio simile Amir Afghani , usando -oper concatenare le opzioni ( il nome termina con .ho con.cpp ):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

E se vuoi davvero usarlo grep , segui la sintassi indicata per --include:

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^

7

Il modo più semplice è

find . -type  f -name '*.extension' | xargs grep -i string 

3

ag (il cercatore d'argento) ha una sintassi abbastanza semplice per questo

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

così

ag -G *.h -G *.cpp CP_Image <path>

usando ag 2.2.0, avevo bisogno di mettere le mie bandiere per ultime:ag _string_to_find_ -G _filename_regex_
Ryanrain il

3

La risposta di seguito è buona:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Ma può essere aggiornato a:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Quale può essere più semplice.


1

Dovrebbe scrivere "-exec grep" per ogni "-o -name"

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

O raggruppali per ()

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

l'opzione '-Hn' mostra il nome e la riga del file.


1

Sono consapevole che questa domanda è un po 'datata, ma vorrei condividere il metodo che utilizzo normalmente per trovare i file .c e .h :

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

o se hai bisogno anche del numero di riga:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.