Lho usato molto, il miglioramento che cerco di ottenere è evitare di echo nomi di file che non corrispondevano in grep. Un modo migliore per farlo?

 for file in `find . -name "*.py"`; do echo $file; grep something $file; done 

Commenti

Risposta

 find . -name "*.py" -exec grep something {} \; -print  

stampa il nome del file dopo le righe corrispondenti.

 find . -name "*.py" -exec grep something /dev/null {} +  

stamperà il nome del file davanti a ogni riga corrispondente (aggiungiamo /dev/null per il caso in cui ce nè solo uno file corrispondente come grep non stampa il nome del file se è passato solo un file in cui cercare. Limplementazione GNU di grep ha unopzione -H come alternativa).

 find . -name "*.py" -exec grep -l something {} +  

stamperà solo i nomi dei file che hanno almeno una riga corrispondente.

Per stampare il nome del file prima delle righe corrispondenti, potresti usare awk invece:

 find . -name "*.py" -exec awk " FNR == 1 {filename_printed = 0} /something/ { if (!filename_printed) { print FILENAME filename_printed = 1 } print }" {} +  

Oppure chiama grep due volte per ogni file, sebbene “d sia meno efficiente in quanto eseguirà almeno un comando grep e fino a due per ogni file (e legga il contenuto del file due volte ):

 find . -name "*.py" -exec grep -l something {} \; \ -exec grep something {} \;  

In ogni caso, non vuoi ripetere loutput di find come quello e ricorda di citare il tuo variabili .

Se si desidera utilizzare un ciclo di shell, con gli strumenti GNU:

 find . -name "*.py" -exec grep -l --null something {} + | xargs -r0 sh -c " for file do printf "%s\n" "$file" grep something < "$file" done" sh  

(funziona anche su FreeBSD e derivati).

Answer

I Se stai usando GNU grep, puoi usare la sua opzione -r o --recursive per fare questa semplice ricerca per te:

 grep -r --include "*.py" -le "$regexp" ./ # for filenames only grep -r --include "*.py" -He "$regexp" ./ # for filenames on each match  

È necessario find se necessario predicati più avanzati.

Commenti

  • A seconda della versione di GNU grep, grep può o non può guardare allinterno di collegamenti simbolici o attraversare collegamenti simbolici alle directory. Potresti anche trovare alcune variazioni nella gestione di altri tipi di file non regolari.

Risposta

Tu può dire a grep di includere il nome del file nelloutput. Quindi, se cè una corrispondenza, verrà mostrata sulla console; se non è presente alcuna corrispondenza allinterno di un file, non verrà stampata alcuna riga per quel file.

find . -name "*.py" | xargs grep -n -H something 

Dal man grep:

-H Always print filename headers with output lines -n, --line-number Each output line is preceded by its relative line number in the file, starting at line 1. The line number counter is reset for each file processed. This option is ignored if -c, -L, -l, or -q is specified. 

Se i tuoi file potrebbero avere nomi con spazi, devi cambiare la pipe per usare i caratteri NUL come separatore. Il comando completo ora avrà il seguente aspetto:

find . -name "*.py" -print0 | xargs -0 grep -n -H something 

Answer

Puoi prova qualcosa come:

find . -name "*.py:" -exec grep -l {} \; 

Questo comando exec grep per ogni file, scoperto dal comando find e dalla sua funzione di comando find standard

Risposta

Usa largomento -l.

for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done 

Un utilizzo più findish sarebbe:

for file in $(find . -name "*.py" -exec grep -l something "{}" +); do echo "$file"; grep something $file; done 

Answer

Lì sono grep alternative che per impostazione predefinita restituiscono i risultati nel formato desiderato. I 2 più popolari che conosco sono ag (noto anche come “the silver searcher”) e ack. ag è pubblicizzato come unalternativa più veloce a ack.

$ ag "^\w+\s*\w+\(" ~/build/i3/src build/i3/src/display_version.c 58:void display_running_version(void) { build/i3/src/load_layout.c 42:static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings = 518:json_content_t json_determine_content(const char *filename) { 575:void tree_append_json(Con *con, const char *filename, char **errormsg) { build/i3/src/x.c 64:CIRCLEQ_HEAD(state_head, con_state) state_head = 67:CIRCLEQ_HEAD(old_state_head, con_state) old_state_head = 70:TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head = 97:void x_con_init(Con *con, uint16_t depth) { ... 

Non posso mostrarti qui, ma loutput è ben colorato. Ottengo i nomi dei file in verde oliva, i numeri di riga in giallo oro e il pezzo corrispondente in ogni riga in rosso sangue. I colori sono personalizzabili.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *