L'uso di xargs nelle risposte sopra non è necessario; puoi ottenere la stessa cosa in questo modo:
find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print
grep -q
significa eseguire in silenzio ma restituire un codice di uscita che indica se è stata trovata una corrispondenza; find
può quindi utilizzare quel codice di uscita per determinare se continuare a eseguire il resto delle sue opzioni. Se -exec grep -q <string-to-match> {} \;
restituisce 0, quindi eseguirà -not -exec grep -q <string-not-to-match>{} \;
. Se anche questo restituisce 0, eseguirà -print
, che stampa il nome del file.
Come ha notato un'altra risposta, usando find
in questo modo ha grandi vantaggi rispetto a grep -Rl
dove vuoi solo cercare file di un certo tipo. Se, d'altra parte, vuoi davvero cercare tutti i file, grep -Rl
è probabilmente più veloce, in quanto utilizza un grep
processo per eseguire il primo filtro per tutti i file, invece di un grep
separato processo per ogni file.
Prova questo:
grep -rl <string-to-match> | xargs grep -L <string-not-to-match>
Spiegazione:grep -lr
fa in modo che grep restituisca in modo ricorsivo (r) un elenco (l) di tutti i file che contengono <string-to-match>
. xargs esegue un ciclo su questi file, chiamando grep -L
su ciascuno di essi. grep -L
produrrà solo il nome del file quando il file non contiene <string-not-to-match>
.
Queste risposte sembrano corrispondere a ENTRAMBE stringhe. Il seguente comando dovrebbe funzionare meglio:
grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'