Použití xargs ve výše uvedených odpovědích není nutné; můžete dosáhnout stejné věci jako je tato:
find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print
grep -q
znamená, že běží tiše, ale vrací výstupní kód indikující, zda byla nalezena shoda; find
pak může tento výstupní kód použít k určení, zda má pokračovat v provádění zbývajících možností. Pokud -exec grep -q <string-to-match> {} \;
vrátí 0, pak bude pokračovat provedením -not -exec grep -q <string-not-to-match>{} \;
. Pokud to také vrátí 0, spustí se -print
, který vypíše název souboru.
Jak poznamenala další odpověď, pomocí find
tímto způsobem má velké výhody oproti grep -Rl
kde chcete prohledávat pouze soubory určitého typu. Pokud na druhou stranu opravdu chcete prohledat všechny soubory, grep -Rl
je pravděpodobně rychlejší, protože používá jeden grep
proces pro provedení prvního filtru pro všechny soubory namísto samostatného grep
proces pro každý soubor.
Zkuste toto:
grep -rl <string-to-match> | xargs grep -L <string-not-to-match>
Vysvětlení:grep -lr
dělá grep rekurzivně (r) výstup seznamu (l) všech souborů, které obsahují <string-to-match>
. xargs tyto soubory zacyklí a volá grep -L
na každém z nich. grep -L
vypíše název souboru pouze v případě, že soubor neobsahuje <string-not-to-match>
.
Zdá se, že tyto odpovědi se shodují OBĚ struny. Následující příkaz by měl fungovat lépe:
grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'