2009-05-19 19 views
11

c'è bisogno di cercare una directory con un sacco di sottodirectory per una stringa all'interno di file:Grep ricorsivo e il conte

sto usando:

grep -c -r "string here" * 

Come posso conteggio totale dei reperti?

Come è possibile eseguire l'output per archiviare solo quei file con almeno un'istanza?

+0

puoi fornire maggiori dettagli come cosa non funziona esattamente? qual è il percorso completo per grep e su quale sistema stai eseguendo questo? – ennuikiller

+0

Puoi chiarire quale output stai vedendo e in che modo ciò che desideri è diverso da quello che ottieni? – Suppressingfire

risposta

9

Funziona per me (ottiene il numero totale di "stringa qui" trovato in ogni file). Tuttavia, non visualizza il totale per TUTTI i file cercati. Ecco come si può ottenere:

grep -c -r 'string' file > out && \ 
    awk -F : '{total += $2} END { print "Total:", total }' out 

L'elenco sarà in fuori e il totale verrà inviato a STDOUT.

Ecco l'output sulla struttura di directory Python2.5.4:

grep -c -r 'import' Python-2.5.4/ > out && \ 
    awk -F : '{total += $2} END { print "Total:", total }' out 
Total: 11500 

$ head out 
Python-2.5.4/Python/import.c:155 
Python-2.5.4/Python/thread.o:0 
Python-2.5.4/Python/pyarena.c:0 
Python-2.5.4/Python/getargs.c:0 
Python-2.5.4/Python/thread_solaris.h:0 
Python-2.5.4/Python/dup2.c:0 
Python-2.5.4/Python/getplatform.c:0 
Python-2.5.4/Python/frozenmain.c:0 
Python-2.5.4/Python/pyfpe.c:0 
Python-2.5.4/Python/getmtime.c:0 

Se si desidera ottenere linee con le occorrenze di 'stringa', modifica a questo:

grep -c -r 'import' Python-2.5.4/ | \ 
    awk -F : '{total += $2; print $1, $2} END { print "Total:", total }' 

che verrà uscita:

[... snipped] 
Python-2.5.4/Lib/dis.py 4 
Python-2.5.4/Lib/mhlib.py 10 
Python-2.5.4/Lib/decimal.py 8 
Python-2.5.4/Lib/new.py 6 
Python-2.5.4/Lib/stringold.py 3 
Total: 11500 

È possibile modificare come i file ($ 1) e il conteggio per file ($ 2) viene stampato.

+0

dove stai assegnando l'estensione di testo? – Codex73

+0

Siamo spiacenti, questo era da una modifica precedente. Le estensioni sono così blah :-) –

+0

come posso produrre solo file con stringa. – Codex73

1

Proverei una combinazione di find e grep.

find . | xargs grep -c "string here" 

In ogni caso, grep -c -r "string here" * funziona per me (Mac OS X).

+0

la stringa è molto grande, quindi xargs non funziona – Codex73

+0

attenti agli spazi nei nomi dei file. considera -print0 e -0 –

9

Utilizzando la sostituzione di processo di Bash, questo fornisce quello che credo sia l'output desiderato? (Si prega di chiarire la questione se non è.)

grep -r "string here" * | tee >(wc -l) 

Questo viene eseguito grep -r normalmente, con l'uscita di andare sia a stdout e ad un processo wc -l.

0

Per emettere solo i nomi dei file con i fiammiferi, utilizzare:

grep -r -l "your string here" . 

il risultato sarà una linea con il nome del file per ogni file che corrisponde all'espressione cercato.

2

qualche soluzione con AWK:

grep -r "string here" * | awk 'END { print NR } 1' 

uno successivo è conteggio totale, il numero di file, e il numero di partite per ciascuna, visualizzando la prima partita di ciascuno (per visualizzare tutte le partite, cambiare la condizione di ++f[$1]):

grep -r "string here" * | 
    awk -F: 'END { print "\nmatches: ", NR, "files: ", length(f); 
        for (i in f) print i, f[i] } !f[$1]++' 

uscita per la prima soluzione (la ricerca all'interno di una directory per "boost::".Ho tagliato manualmente alcune linee troppo lunghe in modo da adattarsi orizzontalmente):

list_inserter.hpp:   return range(boost::begin(r), boost::end(r)); 
list_of.hpp:   ::boost::is_array<T>, 
list_of.hpp:   ::boost::decay<const T>, 
list_of.hpp:   ::boost::decay<T> >::type type; 
list_of.hpp:  return ::boost::iterator_range_detail::equal(l, r); 
list_of.hpp:  return ::boost::iterator_range_detail::less_than(l, r); 
list_of.hpp:  return ::boost::iterator_range_detail::less_than(l, r); 
list_of.hpp:  return Os << ::boost::make_iterator_range(r.begin(), r.end()); 
list_of.hpp:   return range(boost::begin(r), boost::end(r)); 
list_of.hpp:   return range(boost::begin(r), boost::end(r)); 
list_of.hpp:   return range(boost::begin(r), boost::end(r)); 
ptr_list_of.hpp:       BOOST_DEDUCED_TYPENAME boost::ptr_... 
ptr_list_of.hpp:  typedef boost::ptr_vector<T>  impl_type; 
13 

uscita per il secondo

list_inserter.hpp:   return range(boost::begin(r), boost::end(r)); 
list_of.hpp:   ::boost::is_array<T>, 
ptr_list_of.hpp:       BOOST_DEDUCED_TYPENAME boost::ptr_... 

matches: 13 files: 3 
ptr_list_of.hpp 2 
list_of.hpp 10 
list_inserter.hpp 1 

colori nel risultato sono belle (--color=always per grep), ma si rompono quando scende attraverso awk qui. Quindi meglio non abilitarli, a meno che tu non voglia che tutto il tuo terminale sia colorato in seguito :) Ciao!

1
grep -rc "my string" ./ | grep :[1-9] >> file_name_by_count.txt 

Funziona come un fascino.