it-swarm.com.de

Wie finde ich Dateien, die kein bestimmtes Zeichenfolgenmuster enthalten?

Wie finde ich die Dateien im aktuellen Verzeichnis, die nicht das Wort foo enthalten (mit grep)?

468
Senthil Kumar

Der folgende Befehl gibt mir alle Dateien, die das Muster foo nicht enthalten:

find .  -not  -ipath '.*svn*' -exec  grep  -H -E -o -c  "foo"  {} \; | grep 0
16
Senthil Kumar

Wenn Ihr grep die Option -L (Oder --files-without-match) Hat:

$ grep -L "foo" *
748
ghostdog74

Schauen Sie sich ack an. Es macht das .svn Ausschluss für Sie automatisch, gibt Ihnen reguläre Perl-Ausdrücke und ist ein einfacher Download eines einzelnen Perl-Programms.

Das Äquivalent zu dem, was Sie suchen, sollte in ack sein:

ack -L foo
44
Andy Lester

Mit dem folgenden Befehl wird ausgeschlossen, dass der Suchvorgang die svn -Ordner mithilfe eines zweiten grep herausfiltern muss.

grep -rL "foo" ./* | grep -v "\.svn"
13
user999305

Sie benötigen tatsächlich:

find .  -not  -ipath '.*svn*' -exec  grep  -H -E -o -c  "foo"  {} \; | grep :0\$
9
Forrest Tiffany

Ich hatte viel Glück mit

grep -H -E -o -c "foo" */*/*.ext | grep ext:0

Meine Versuche mit grep -v gab mir nur alle Zeilen ohne "foo".

6
Johnny

Du kannst es mit grep alleine machen (ohne zu finden).

grep -riL "foo" .

Dies ist die Erklärung der Parameter, die für grep verwendet werden.

     -L, --files-without-match
             each file processed.
     -R, -r, --recursive
             Recursively search subdirectories listed.

     -i, --ignore-case
             Perform case insensitive matching.

Wenn Sie l (in Kleinbuchstaben) verwenden, erhalten Sie das Gegenteil (Dateien mit Übereinstimmungen)

     -l, --files-with-matches
             Only the names of files containing selected lines are written
5
Adrian

Problem

Ich muss ein großes Projekt umgestalten, das .phtml - Dateien verwendet, um HTML mit Inline PHP - Code zu schreiben. Ich möchte stattdessen Moustache - Vorlagen verwenden möchten alle .phtml - Giles finden, die den String new Mustache nicht enthalten, da diese noch umgeschrieben werden müssen.

Lösung

find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'

Erklärung

Vor den Rohren:

Finden

find . Dateien rekursiv suchen, beginnend in diesem Verzeichnis

-iname '*.phtml' Dateiname muss .phtml Enthalten (bei i wird die Groß-/Kleinschreibung nicht beachtet)

-exec 'grep -H -E -o -c 'new Mustache' {}' Führen Sie den Befehl grep für jeden der übereinstimmenden Pfade aus

Grep

-H Drucken Sie Dateinamenüberschriften immer mit Ausgabezeilen.

-E Interpretiere das Muster als erweiterten regulären Ausdruck (d. H. Zwinge grep, sich als egrep zu verhalten).

-o Druckt nur den passenden Teil der Zeilen.

-c Nur eine Anzahl ausgewählter Zeilen wird in die Standardausgabe geschrieben.


Hiermit erhalte ich eine Liste aller Dateipfade, die mit .phtml Enden, und zähle, wie oft die Zeichenfolge new Mustache In jedem von ihnen vorkommt.

$> find . -iname '*.phtml$' -exec 'grep -H -E -o -c 'new Mustache' {}'\;

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/orders.phtml:1
./app/MyApp/Customer/View/Account/banking.phtml:1
./app/MyApp/Customer/View/Account/applycomplete.phtml:1
./app/MyApp/Customer/View/Account/catalogue.phtml:1
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0

Die erste Pipe grep :0$ Filtert diese Liste, um nur Zeilen einzuschließen, die mit :0 Enden:

$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0

Die zweite Pipe sed 's/..$//' Entfernt die letzten beiden Zeichen jeder Zeile und lässt nur die Dateipfade übrig.

$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml
./app/MyApp/Customer/View/Account/studio.phtml
./app/MyApp/Customer/View/Account/classadd.phtml
./app/MyApp/Customer/View/Account/orders-trade.phtml
2
Gruffy

find *20161109* -mtime -2|grep -vwE "(TRIGGER)"

Sie können den Filter unter "find" und die Ausschlusszeichenfolge unter "grep -vwE" angeben. Verwenden Sie mtime unter find, wenn Sie auch nach geänderter Zeit filtern müssen.

1
zandeep

Mein grep hat keine -L Option. Ich finde Abhilfe, um dies zu erreichen.

Die Ideen sind:

  1. um den ganzen Dateinamen mit der verdienten Zeichenkette in eine txt1.txt abzulegen.
  2. speichern Sie den gesamten Dateinamen im Verzeichnis in einer txt2.txt.
  3. machen Sie den Unterschied zwischen der 2-Dump-Datei mit dem Befehl diff.

    grep 'foo' *.log | cut -c1-14 | uniq > txt1.txt
    grep * *.log | cut -c1-14 | uniq > txt2.txt
    diff txt1.txt txt2.txt | grep ">"
    
1
user6305682

Öffnen Sie den Fehlerbericht

Wie von @tukan kommentiert, gibt es einen offenen Fehlerbericht für Ag bezüglich des Flags -L/--files-without-matches:

Da der Fehlerbericht kaum Fortschritte macht, sollte die unten erwähnte Option -L nicht verwendet werden, solange der Fehler nicht behoben wurde. Verwenden Sie stattdessen verschiedene Ansätze, die in diesem Thread vorgestellt werden. Zitieren eines Kommentars für den Fehlerbericht [Schwerpunkt meiner]:

Irgendwelche Updates dazu? -L Ignoriert Übereinstimmungen in der ersten Zeile der Datei vollständig. Wenn dies nicht bald behoben werden soll , sollte das Flag vollständig entfernt werden, da es effektiv überhaupt nicht wie angekündigt funktioniert .


The Silver Searcher - Ag (vorgesehene Funktion - siehe Fehlerbericht)

Als leistungsstarke Alternative zu grep können Sie The Silver Searcher - Ag verwenden:

Ein Code-Such-Tool, das ack ähnelt und sich auf Geschwindigkeit konzentriert.

Wenn wir uns man ag Ansehen, finden wir die Option -L Oder --files-without-matches:

...

OPTIONS
    ...

    -L --files-without-matches
           Only print the names of files that don´t contain matches.

Das heißt, um rekursiv nach Dateien zu suchen, die nicht mit foo übereinstimmen, aus dem aktuellen Verzeichnis:

ag -L foo

Um das Verzeichnis current nur nach Dateien zu durchsuchen, die nicht mit foo übereinstimmen, geben Sie einfach --depth=0 Für die Rekursion an:

ag -L foo --depth 0
1
dfri