Come posso trovare tutti i file che NON contengono una stringa di testo?


40

Quale comando conciso posso usare per trovare tutti i file che NON contengono una stringa di testo?

Ho provato questo (usando -v per invertire i parametri di grep) senza fortuna:

find . -exec grep -v -l shared.php {} \;

Qualcuno ha detto che avrebbe funzionato:

find . ! -exec grep -l shared.php {} \;

Ma non sembra funzionare per me.

Questa pagina ha questo esempio:

find ./logs -size +1c  > t._tmp
while read filename
do
     grep -q "Process Complete" $filename
     if [ $? -ne 0 ] ; then
             echo $filename
     fi
done < t._tmp
rm -f t_tmp

Ma è ingombrante e per niente conciso.

ps: so che grep -L *lo farà, ma come posso usare il comando find in combinazione con grep per i file esclusi.

pss: Inoltre non sono sicuro di come grep includa le sottodirectory con la grep -L *sintassi, ma voglio ancora sapere come usarlo find:)


1
Il primo comando che hai scritto ha funzionato bene sul mio computer. Quale versione di find stai usando? E dato che ci siamo, forse specifica quale Unix stai eseguendo ..
Rahmu,

@rahmu, questo comando quasi sempre non funziona come previsto. Probabilmente hai avuto un caso molto specifico. Si prega di consultare unix.stackexchange.com/questions/339619/…
sgnsajgon,

Risposte:


8
find . -type f | xargs grep -H -c 'shared.php' | grep 0$ | cut -d':' -f1    

O

find . -type f -exec grep -H -c 'shared.php' {} \; | grep 0$ | cut -d':' -f1

Qui stiamo calcolando il numero di righe corrispondenti (usando -c) in un file se il conteggio è 0, allora è il file richiesto, quindi tagliamo la prima colonna, ovvero il nome file dall'output.


6
Questo è terribilmente complicato. Vedi la risposta di Kevin .
Gilles 'SO- smetti di essere malvagio' il

@Gilles sì, sono d'accordo con te. Ho +1 la sua risposta.
Sachin Divekar,

6
Questo non è solo "tremendamente complicato" ma è sbagliato in quanto elenca anche tutti i file che contengono un multiplo di 10 righe corrispondenti al modello. Anche se grepfosse stato risolto, questo non avrebbe assunto nessun nome di file contenente :o caratteri di nuova riga ...
don_crissti

@don_crissti, grazie per averlo menzionato! Tuttavia, a meno che tu non usi molto codice copia-incolla, la soluzione sopra è un bel trucco.
Ufo

@Ufos - Davvero non capisco il tuo commento ... Questo è sbagliato . Ad ogni modo, sentiti libero di usarlo se ti sembra un "trucco davvero bello" ...
don_crissti

58

La tua ricerca dovrebbe funzionare se cambi -v -l(file che non hanno alcuna riga corrispondente) in -L(file senza righe corrispondenti), ma puoi anche usare grepl' -ropzione recursive ( ):

grep -rL shared.php .

quale scoperta dovrebbe funzionare?
Cwd

@Kevin - scusa, find . -exec grep -v -l shared.php {} \;(e tutte le altre varianti che ho provato) non funziona per me. Sono su OS X ma non penso che dovrebbe importare. Ti ho dato un +1 perché mi ero dimenticato -rdell'opzione.
Cwd

@cwd so che questo è vecchio ma voglio lasciarlo qui per i futuri lettori: il fatto che tu sia su OS X fa la differenza. Mac OSX usa i comandi di FreeBSD. Molte persone qui assumono comandi in stile Linux (GNU). Hanno argomenti diversi, modi diversi di gestire i dettagli.
Rich Homolka,

A partire dal 2016 OSX sembra supportare-L
David Moles

@kevin Ho detto che lo fa, non che non lo faccia. :) non che qualcuno abbia esplicitamente dichiarato di no, ma i commenti erano confusi (e ho sicuramente incontrato altri problemi di OS X / BSD vs GNU).
David Moles,

4

So che grep -L *lo farà, ma come posso usare il findcomando in combinazione con grepper escludere i file è ciò che voglio davvero sapere

Puoi usare finde grepcosì:

find . -type f ! -exec grep -q 'PATTERN' {} \; -print

Qui -printviene eseguito solo se l'espressione precedente: ! -exec ... {}valuta come true.
Quindi, per ogni file trovato, grep -q 'PATTERN'viene utilizzato exec, se il risultato è falsequindi l'intera espressione viene ! -exec grep -q 'PATTERN'valutata come truee il nome del file viene modificato print.


2
Quello ha il vantaggio di essere standard e portatile.
Stéphane Chazelas,

C'è una differenza con GNU, grep -Lanche se includerà anche i file non leggibili nell'elenco.
Stéphane Chazelas,

1

Il risultato non corrisponde all'opzione -L

grep -iL shared.php .

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.