Die Verwendung von xargs in den obigen Antworten ist nicht erforderlich; Sie können dasselbe wie folgt erreichen:
find . -type f -exec grep -q <string-to-match> {} \; -not -exec grep -q <string-not-to-match> {} \; -print
grep -q bedeutet leise laufen, aber einen Beendigungscode zurückgeben, der angibt, ob eine Übereinstimmung gefunden wurde; find kann dann diesen Exit-Code verwenden, um zu bestimmen, ob der Rest seiner Optionen weiterhin ausgeführt werden soll. Wenn -exec grep -q <string-to-match> {} \; gibt 0 zurück, dann wird -not -exec grep -q <string-not-to-match>{} \; ausgeführt . Wenn das auch 0 zurückgibt, wird es mit der Ausführung von -print fortfahren , die den Namen der Datei ausgibt.
Wie eine andere Antwort angemerkt hat, verwenden Sie find hat auf diese Weise große Vorteile gegenüber grep -Rl wo Sie nur Dateien eines bestimmten Typs suchen möchten. Wenn Sie hingegen wirklich alle Dateien durchsuchen möchten, grep -Rl ist wahrscheinlich schneller, da es einen grep verwendet Prozess, um den ersten Filter für alle Dateien durchzuführen, anstelle eines separaten grep Prozess für jede Datei.
Versuchen Sie Folgendes:
grep -rl <string-to-match> | xargs grep -L <string-not-to-match>
Erläuterung:grep -lr lässt grep rekursiv (r) eine Liste (l) aller Dateien ausgeben, die <string-to-match> enthalten . xargs durchläuft diese Dateien und ruft grep -L auf auf jedem von ihnen. grep -L gibt den Dateinamen nur aus, wenn die Datei <string-not-to-match> nicht enthält .
Diese Antworten scheinen als die Übereinstimmung BOTH zu gelten Saiten. Der folgende Befehl sollte besser funktionieren:
grep -l <string-to-match> * | xargs grep -c <string-not-to-match> | grep '\:0'