Utilizza grep –exclude / – include syntax per non eseguire il grep attraverso determinati file

Sto cercando la stringa foo= nei file di testo in un albero di directory. È su una macchina Linux comune, ho una shell bash:

 grep -ircl "foo=" * 

Nelle directory ci sono anche molti file binari che corrispondono a “foo =”. Poiché questi risultati non sono rilevanti e rallentano la ricerca, voglio grep per saltare la ricerca di questi file (principalmente immagini JPEG e PNG). Come potrei farlo?

So che ci sono le opzioni --exclude=PATTERN e --include=PATTERN , ma qual è il formato del pattern? La pagina man di grep dice:

 --include=PATTERN Recurse in directories only searching file matching PATTERN. --exclude=PATTERN Recurse in directories skip file matching PATTERN. 

Cercando su grep include , grep include exclude , grep exclude e varianti non hanno trovato nulla di rilevante

Se c’è un modo migliore di fare il grepping solo in certi file, sono tutto per lui; spostare i file incriminati non è un’opzione. Non riesco a cercare solo certe directory (la struttura delle directory è un bel casino, con tutto ovunque). Inoltre, non posso installare nulla, quindi ho a che fare con strumenti comuni (come grep o la ricerca suggerita).

Usa la syntax della shell globbing:

 grep pattern -r --include=\*.{cpp,h} rootdir 

La syntax per --exclude è identica.

Si noti che la stella viene sfuggita con una barra rovesciata per impedire che venga espansa dalla shell (citandola, ad esempio --include="*.{cpp,h}" , funzionerebbe altrettanto bene). Altrimenti, se nella directory di lavoro corrente sono presenti file corrispondenti al pattern, la riga di comando si espanderebbe in qualcosa come grep pattern -r --include=foo.cpp --include=bar.h rootdir , che grep pattern -r --include=foo.cpp --include=bar.h rootdir solo i file chiamato foo.cpp e bar.h , che è molto probabilmente non quello che volevi.

Se vuoi solo saltare i file binari, ti suggerisco di guardare l’opzione -I (maiuscolo i). Ignora i file binari. Uso regolarmente il seguente comando:

 grep -rI --exclude-dir="\.svn" "pattern" * 

Cerca in modo ricorsivo, ignora i file binari e non guarda all’interno delle cartelle nascoste di Subversion, per qualunque modello io voglia. Ho alias come “grepsvn” sulla mia scatola al lavoro.

Si prega di dare un’occhiata a Ack , che è stato progettato proprio per queste situazioni. Il tuo esempio di

 grep -ircl --exclude=*.{png,jpg} "foo=" * 

è fatto con ack come

 ack -icl "foo=" 

perché Ack non guarda mai nei file binari per impostazione predefinita e -r è attivo per impostazione predefinita. E se vuoi solo i file CPP e H, allora fallo

 ack -icl --cpp "foo=" 

grep 2.5.3 ha introdotto il parametro –exclude-dir che funzionerà nel modo desiderato.

 grep -rI --exclude-dir=\.svn PATTERN . 

Puoi anche impostare una variabile di ambiente: GREP_OPTIONS = “- exclude-dir = .svn”

Però secondo il voto di Andy per ack , è il migliore.

Ho trovato questo dopo molto tempo, è ansible aggiungere più include ed esclude come:

 grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js 

Il comando suggerito:

 grep -Ir --exclude="*\.svn*" "pattern" * 

è concettualmente sbagliato, perché –exclude funziona sul basename. In altre parole, salterà solo il .svn nella directory corrente.

In grep 2.5.1 devi aggiungere questa linea a ~ / .bashrc o ~ / .bash profile

 export GREP_OPTIONS="--exclude=\*.svn\*" 

Trovo che l’output di grep di grep sia molto utile a volte:

 grep -rn "foo=" . | grep -v "Binary file" 

Tuttavia, questo in realtà non impedisce di cercare i file binari.

Su CentOS 6.6 / Grep 2.6.3, devo usarlo in questo modo:

 grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*" 

Notare la mancanza di segni di uguale “=” (altrimenti --include , --exclude , include-dir e --exclude-dir vengono ignorati)

Se non sei contrario a find , mi piace la sua funzione -prune :

 trova [directory] \
         -name "pattern_to_exclude" -prune \
      -o -name "another_pattern_to_exclude" -prune \
      -o -name "pattern_to_INCLUDE" -print0 \
 |  xargs -0 -I FILENAME grep -IR "pattern" FILENAME

Sulla prima riga, si specifica la directory che si desidera cercare. . (directory corrente) è un percorso valido, ad esempio.

Sulla 2a e 3a riga, utilizzare "*.png" , "*.gif" , "*.jpg" e così via. Usa tanti di questi -o -name "..." -prune costrutti come hai dei pattern.

Sulla quarta riga, hai bisogno di un altro -o (specifica “o” per find ), i pattern che vuoi e hai bisogno di un -print o -print0 alla fine di esso. Se vuoi solo “tutto il resto” che rimane dopo aver potato le immagini *.gif , *.png , ecc., Usa -o -print0 e hai finito con la 4a linea.

Infine, sulla quinta riga c’è la pipe to xargs che prende ciascuno di questi file risultanti e li memorizza in una variabile FILENAME . Quindi passa grep the -IR flags, il "pattern" , e quindi FILENAME viene espanso da xargs per diventare quella lista di nomi di file trovati da find .

Per la tua particolare domanda, la dichiarazione può sembrare qualcosa di simile:

 trova .  \
      -name "* .png" -prune \
      -o -name "* .gif" -prune \
      -o -name "* .svn" -spring \
      -o -print0 |  xargs -0 -I FILES grep -IR "foo =" FILES

Sono un dilettante, garantito, ma ecco come appare il mio ~ / .bash_profile:

 export GREP_OPTIONS = "- orl --exclude-dir = .svn --exclude-dir = .cache --color = auto" GREP_COLOR = '1; 32'

Nota che per escludere due directory, dovevo usare –exclude-dir due volte.

Prova questo:

  $ trovare.  -name "* .txt" -tipo f -print |  file xargs |  grep "foo =" |  cut -d: -f1

Fondato qui: http://sofit.miximages.com/unix/ppre codefind . -not -name ‘.png’ -o -type f -print | xargs grep -icl “foo=”

questi script non risolvono tutto il problema … Provalo meglio:

 du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1" 

questo script è molto migliore, perché usa espressioni regolari “reali” per evitare le directory dalla ricerca. basta separare i nomi delle cartelle o dei file con “\ |” sulla grep -v

divertirsi! trovato sulla mia shell linux! XD

Guarda @ questo.

 grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags 

Se si esegue una ricerca non ricorsiva, è ansible utilizzare i pattern di glop in modo che corrispondano ai nomi dei file.

 grep "foo" *.{html,txt} 

include html e txt. Cerca solo nella directory corrente.

Per cercare nelle sottodirectory:

  grep "foo" */*.{html,txt} 

Nelle sottodirectory:

  grep "foo" */*/*.{html,txt} 

git grep

Usa git grep che è ottimizzato per le prestazioni e mira a cercare attraverso determinati file.

Di default ignora i file binari e sta onorando il tuo .gitignore . Se non stai lavorando con la struttura di Git, puoi ancora usarlo passando --no-index .

Sintassi di esempio:

 git grep --no-index "some_pattern" 

Per ulteriori esempi, vedi:

  • Come escludere determinate directory / file dalla ricerca di git grep .
  • Controlla se tutte le stringhe o espressioni rege multiple esistono in un file

L’ --binary-files=without-match per GNU grep ottiene di saltare i file binari. (Equivalente allo switch -I menzionato altrove).

(Questo potrebbe richiedere una versione recente di grep ; 2.5.3 ce l’ha, almeno.)

adatto per il file tcsh .alias:

 alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *' 

Ci ho messo un po ‘a capire che la porzione {mm, m, h, cc, c} NON dovrebbe essere racchiusa tra virgolette. ~ Keith

Nelle directory ci sono anche molti file binari. Non riesco a cercare solo certe directory (la struttura delle directory è un bel casino). C’è un modo migliore di grepping solo in determinati file?

ripgrep

Questo è uno degli strumenti più veloci progettati per cercare ricorsivamente la directory corrente. È scritto in Rust , costruito sopra il motore regex di Rust per la massima efficienza. Controlla l’ analisi dettagliata qui .

Quindi puoi solo eseguire:

 rg "some_pattern" 

.gitignore tuo .gitignore e salta automaticamente file / directory e file binari nascosti.

Puoi ancora personalizzare includere o escludere file e directory usando -g / --glob . Le regole di Globbing corrispondono ai globi di segno. Controlla man rg per aiuto.

Per ulteriori esempi, vedi: Come escludere alcuni file che non corrispondono ad alcune estensioni con grep?

Su macOS, puoi installare tramite brew install ripgrep .

Per ignorare tutti i risultati binari di grep

 grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}' 

La parte di awk filtrerà tutte le righe del file binario foo

Prova questo:

  1. Crea una cartella denominata ” --F ” sotto currdir .. (o collega un’altra cartella lì rinominata in ” --F ” cioè double-minus-F .
  2. #> grep -i --exclude-dir="\-\-F" "pattern" *