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
- Correlati (su Chiedi a Ubuntu ): Cerca in modo ricorsivo un pattern / testo solo nel nome file specificato di una directory?
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.