Löschen Sie Dateien mit bestimmten Inhalten

Löschen Sie Dateien mit bestimmten Inhalten

Wenn sich in einem Verzeichnis Tausende von Datendateien (mit derselben Erweiterung) befinden, wie lösche ich diejenigen, die eine bestimmte Parameteranweisung enthalten?

Wenn ich beispielsweise alle Dateien löschen möchte, die die Zeile enthalten

Key = 0

könnte ich so etwas machen wie

grep -i "Key = 0" * | rm *

Antwort1

Sie können den folgenden Befehl in der Shell verwenden. Dies sollte funktionieren, wenn das zu suchende Muster istKey = 0

grep -lrIZ "Key = 0" . | xargs -0 rm -f --

Allgemeiner Befehl:

grep -lrIZ "<Pattern to be searched in the file>" . | xargs -0 rm -f --

Antwort2

Das Hauptproblem bei der Pipeline, die grep+ verwendet, rmbesteht darin, dass sie rmnicht aus ihrem Standardeingabestream liest, was bedeutet, dass sie nichts vom grepBefehl auf der linken Seite der Pipe liest.

Stattdessen rm *würde die Anweisung auf der rechten Seite der Pipe sämtliche Eingaben ignorieren und rmfür jeden sichtbaren Dateinamen im aktuellen Verzeichnis ausgeführt werden.

Wenn Sie das Problem mit rmdem Nichtlesen der Standardeingabe ignorieren, grepweist Ihr Befehl zwei Hauptprobleme auf:

  1. Es werden passende Zeilen mit Dateinamen ausgegeben. Dies wäre nutzlos, rmda wir wissen müssennurdie Dateinamen der Dateien, die wir löschen möchten.
  2. Es passt Key = 0alsTeilzeichenfolge, das heißt, es passt auch Crypto Key = 0x01usw.

find . -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +

oder mit GNU find(und einigen anderen),

find . -type f -exec grep -q -F -x 'Key = 0' {} \; -delete

Beide würden nach regulären Dateien im aktuellen Verzeichnis oder darunter suchen und für jede gefundene Datei ausführen grep -q -F -x 'Key = 0'. Dieser grepBefehl würde einen Exit-Status zurückgeben, der angibt, ob es in der Datei eine Zeile gibt, diegenau Key = 0(und sonst nichts).

Der zweite findBefehl löscht die Datei unter Verwendung ihres -deletePrädikats, wenn eine solche Zeile gefunden wird. Der erste findBefehl sammelt die Pfadnamen der Dateien, die diese Zeile enthalten, und führt rm -fsie dann stapelweise aus.

Die verwendeten Flaggen grepsind

  • -q, für den stillen Betrieb. Das Dienstprogramm gibt keine übereinstimmenden Zeilen aus, wird aber nach der ersten Übereinstimmung erfolgreich beendet oder mit einem Exit-Status ungleich Null, wenn die Datei keine Übereinstimmung enthält.
  • -F, für feste Zeichenfolgenübereinstimmung. Wir führen die Übereinstimmung mit einer Zeichenfolge durch, nicht mit einem regulären Ausdruck.
  • -x, um nur vollständige Zeilenübereinstimmungen zu finden. Dies hat denselben Effekt, als ob Sie einen regulären Ausdruck verwenden würden, der sowohl am Anfang als auch am Ende der Zeile verankert ist.

Ich verwende hier nicht „ -iwith“ grep, da dadurch auch Dateien gelöscht würden, die Zeilen wie KEY = 0und kEY = 0usw. enthalten, und Sie haben nichts zu diesen Groß-/Kleinschreibungsunterschieden gesagt.

Möchten Sie, dass der findBefehl auf ein bestimmtes Dateinamensuffix beschränkt wird, wie etwa .ext, dann verwenden Sie -name '*.ext'im findBefehl vor der Ausführung von grep. Beispiel:

find . -name '*.ext' -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +

verwandte Informationen