Trovare una sottostringa nei file attraverso le sottodirectory con un singolo comando integrato?


10

In Windows, se volessi trovare una stringa in tutti i file in tutte le sottodirectory, farei qualcosa del genere

findstr /C:"the string" /S *.h

Tuttavia, in Linux (per esempio, Ubuntu) ho trovato nessun altro modo se non un po 'di comando pipe che coinvolgono find, xargse grep(un esempio è in questa pagina: ? Come posso ricorsivamente grep attraverso sotto-directory ). Tuttavia, la mia domanda è diversa: esiste un singolo comando integrato che funziona attraverso questa magia, senza dover scrivere il mio script di shell?

Risposte:


19

GNU grep consente la ricerca ricorsiva attraverso le sottodirectory:

grep -r --include='*.h' 'the string' .

Ho provato questa esatta riga di comando in Ubuntu ma ottengo "grep: opzione non valida - 'M'" anche se non riesco a vedere nessuna 'M' da nessuna parte ... sconcertante
Guido Domenici

@Guido Funziona benissimo qui
phunehehe

In una modifica suggerita TomasG consiglia di modificare l'ultimo *in '*': "È necessario citare l'ultimo carattere jolly per evitare errori quando parte del nome file inizia con -"
Michael Mrozek

In una strana svolta di eventi, ora funziona anche per me, come indicato nella risposta originale. Grazie!
Guido Domenici,

1
@Guido: il problema potrebbe essere stato causato da un file nella directory corrente chiamato -Msomethingo da GREP_OPTIONSun'impostazione.
Gilles 'SO- smetti di essere malvagio' il

2

grep -r searchpattern /path/to/start/in

Dove /path/to/start/in/può essere solo " ." per la directory corrente.



0

c'è un singolo comando integrato che funziona attraverso questa magia ...?

Per essere pedanti, no, non puoi presumere che esista un simile comando .

Esistono molte implementazioni diverse di Unix e ognuna ha le sue diverse stranezze. POSIX, il comune denominatore (e la cosa più vicina a uno standard in Unices) non specifica tale opzione pergrep .

Come menzionato in altre risposte, l'implementazione di GNU grepha un'opzione non standard che fa quello che vuoi. Sebbene questa particolare implementazione possa essere comune sui sistemi Linux, non puoi assumere la sua disponibilità su nessun Unix, nemmeno su alcuni sistemi Linux.

Infine, dovrei menzionare che è la filosofia Unix quella di favorire la combinazione di diversi programmi primitivi, rispetto all'uso di un grande eseguibile monolitico che tenta di fare tutto in una volta.

Nel tuo caso, la scansione del file system e la corrispondenza di regexp in un flusso sono due attività separate. È normale trattare ciascuno in un programma separato.


0

Per trovare una stringa da una determinata directory, usa il comando seguente

find <fullDirectoryPath> -name '*' -exec grep -l '<StringToFind>' {} \;

Per esempio:

find /apps_bev/apps/xfer/export/02210 -name '*' -exec grep -l '38221000001032' {} \;

1
greppuò prendere più di un file come argomento, quindi dovresti usare +invece di \;evitare di eseguire una grepchiamata per file che è abbastanza inefficiente.
Stéphane Chazelas,

1
Si noti che si -name '*'limita ai file il cui nome è testo valido nella locale corrente ( findalmeno in alcune implementazioni), ma gli altri componenti della directory potrebbero contenere sequenze di byte che non formano caratteri validi. Se la tua intenzione -name '*'era quella di assicurarti che l'output fosse un testo valido (omettendo i file con nomi impropri), preferiresti usare find ... ! -name '*' -prune -o -exec grep ... {} +, il che impedirebbe anche finddi scendere in directory con nomi impropri.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.