Bash: c'è un modo per cercare una string particolare in una directory di file?

Possibile duplicazione:
Cercare un model di text in Linux

In bash, mi chiedevo se c'erano dei comandi che ti permettano di sapere se esiste una string particolare all'interno dei file che si trovano nella directory corrente in cui ci si trova.

Dite di cercare la function 'toUpperCase ()' all'interno di un insieme di file C nella directory corrente. Ci sono molti file, quindi non si desidera aprire manualmente ciascuno con vim e controllare la string 'toUpperCase' perché ciò richiederebbe molto tempo. Se non una linea di command bash, esiste un altro metodo per farlo in modo efficiente?

Con grep :

 grep -R "toUppercase()" * 

Oppure, se avete installato ack-grep , semplicemente:

 ack-grep "toUppercase" 

Se si desidera limitare la ricerca nei file C, con ack-grep :

 ack-grep -cc "toUppercase()" 

ack-grep può essere installato anche su OSX ma l'eseguibile viene chiamato solo ack .

Lo strumento di ricerca standard di text è grep .

Per cercare la string toUpperCase( in tutti i file .c nella directory corrente:

 grep -F 'toUpperCase(' *.c 

Se si desidera esaminare anche le sottodirectory:

 grep -r --include='*.c' -F 'toUpperCase(' 

Se stai cercando le chiamate di function C, allora i ctag possono essere una misura migliore. È ansible eseguire una volta su tutti i file di origine per creare un indice di identificatori, quindi utilizzare l'editor per navigare tra le chiamate. Tutti i redattori vi-like possono utilizzare il file TAGS di ctags. Se si utilizza Emacs, eseguire i programmi etags simili.

Stai usando vim. Hai un attrezzo per farlo costruito.

Probabilmente, ci sono sette risposte che già dicono di usare grep . Ma io sembro essere l'unica persona finora che abbia notato dalla tua domanda che stai usando vim . Come tale, anche se è ansible utilizzare grep dall'interno vim , è anche ansible utilizzare lo strumento incorporato di vim . Questo viene richiamato tramite il command :vimgrep .

Per cercare "tutti i file di origine C nella directory corrente per le chiamate alla function toUpperCase() " si digita il command vim

 :vimgrep "\<toUpperCase\_s*(" *.c 

L'elenco risultante delle partite viene automaticamente caricato nell'elenco dei quickfix, accessibile con uno di essi (vedere l'aiuto on-line per la differenza sottile)

 :copen :cwin 

Per trovare la definizione di function, piuttosto che le chiamate ad esso, ctags è lo strumento, come indicato nella risposta di Gilles , in combinazione con i :tjump o :tselect .

Perché utilizzare :vimgrep ?

L'aiuto in linea ( :help grep ) enumera numerose ragioni, che non ho qui pappagallo. Oltre a questi, confrontare l'azione di :vimgrep con quella della dietbuddha di dietbuddha . La linea di command dietbuddha forks un process individuale grep per each singolo file di origine C. Non utilizza nemless xargs per ridurre tale sovraccarico. E ancora wherete analizzare in qualche modo l'output per ricall l'editor di text sui file di origine rilevanti una volta terminato. :vimgrep non fork off molti processi aggiuntivi a tutti, e usando il risultato è la semplicità stessa. La semplice selezione di una delle voci nell'elenco di quickfix risultante posiziona automaticamente il cursore sulla row corrispondente del relativo file di origine.

In realtà, esegue esattamente quello che hai scritto che faresti a mano, tranne automaticamente. È il modo automatico di fare quelle azioni di editor di text. Carica il file come se fosse caricato manualmente, la ricercherà per un'espressione regolare (usando la stessa syntax di espressione regolare già utilizzata altrove in vim ), registra i luoghi in cui si verificano le corrispondenze e quindi scarica il file.

Sì, lo strumento è chiamato grep .

Il command grep cerca uno o più file di input per le righe contenenti una corrispondenza a un model specificato. Per impostazione predefinita, grep printing le righe corrispondenti.

L'utilizzo di base è:

 grep something somewhere 

Oppure, più in particolare:

 grep [some options] pattern file 

In un caso molto semplice, ricorsivamente volete cercare tutti i file, fornendo così l'opzione -r . Se non ti interessa la maiuscola o la minuscola, renderla insensata ai casi con l'opzione -i .

 grep -ri "touppercase()" . 

Se si desidera solo le parti corrispondenti, utilizzare l'opzione -o .

Grep può usare espressioni regolari e ha un enorme manuale .

grep è la risposta standard – usando il flag -r per ricercare ricorsivamente o in combinazione con find (discussioni ed esempi in altre domande su questo sito, come ad esempio)

La mia scelta preferita recentemente è ack . Non è probabilmente installato sul tuo computer, ma puoi installarlo usando apt-get su Ubuntu o semplicemente scaricare. I collegamenti, le istruzioni e le ragioni che è meglio di grep sono disponibili all'indirizzo http://betterthangrep.com/

Grep farà il trucco, ma un po 'di script aggiuntivi aiuterà a trovare il nome del file e la linea esatta riferita. Se questo è quello che vuoi trovo bene i seguenti lavori. Lo ho salvato come uno script di shell e lo passa al valore che voglio come prima opzione di row di command.

 for i in $(ls) do cat $i 2> /dev/null | grep $1 > /dev/null 2>&1 STATUS=$? if [ $STATUS -eq 0 ] ; then echo $i cat $i | grep -n $1 fi done 

find e grep

find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print

perché non solo grep ?

grep -r string . recurserà attraverso tutti i file nella directory corrente. Se si dispone di file object o altri binari, è ansible get una corrispondenza con i risultati binari aka. spazzatura. Se accade anche di avere file fifos o device nella vostra sottodirectory, potresti avere conseguenze sconosciute / non intenzionali.

grep string *.c ricerca solo i file correnti .c .

grep string **/*.c cerca tutte le sottodirectory. Tuttavia, se si dispone di un numero molto grande di file .c , si esegue il rischio di superare il numero massimo di espansioni per il globo di shell. Anche l'espansione deve verificarsi innanzitutto, il che significa una traversa piena dell'tree prima che inizia il grep .

Mi sembra interessante che nessuno abbia risposto alla tua domanda specifica: "come posso trovare se esiste una string particolare all'interno dei file che si trovano nella directory corrente". Per quanto so che non esiste un'opzione grep che ritorna solo se una corrispondenza è stata trovata in un gruppo di file. L'opzione più vicina è -l per elencare i nomi dei file. La risposta più vicina a quelli finora è da tim, con alcune piccole modifiche:

 #!/usr/bin/bash for i in $(ls *.c 2> /dev/null) do cat $i 2> /dev/null | grep $1 > /dev/null 2>&1 STATUS=$? if [ $STATUS -eq 0 ] ; then echo "Found" exit fi done echo "Not found" 

È ansible rendere questo script shell più generico accettando un secondo argomento per l'estensione del file senza troppi problemi.

Doug