![Löschen Sie Dateien mit bestimmten Inhalten](https://rvso.com/image/178487/L%C3%B6schen%20Sie%20Dateien%20mit%20bestimmten%20Inhalten.png)
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, rm
besteht darin, dass sie rm
nicht aus ihrem Standardeingabestream liest, was bedeutet, dass sie nichts vom grep
Befehl auf der linken Seite der Pipe liest.
Stattdessen rm *
würde die Anweisung auf der rechten Seite der Pipe sämtliche Eingaben ignorieren und rm
für jeden sichtbaren Dateinamen im aktuellen Verzeichnis ausgeführt werden.
Wenn Sie das Problem mit rm
dem Nichtlesen der Standardeingabe ignorieren, grep
weist Ihr Befehl zwei Hauptprobleme auf:
- Es werden passende Zeilen mit Dateinamen ausgegeben. Dies wäre nutzlos,
rm
da wir wissen müssennurdie Dateinamen der Dateien, die wir löschen möchten. - Es passt
Key = 0
alsTeilzeichenfolge, das heißt, es passt auchCrypto Key = 0x01
usw.
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 grep
Befehl 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 find
Befehl löscht die Datei unter Verwendung ihres -delete
Prädikats, wenn eine solche Zeile gefunden wird. Der erste find
Befehl sammelt die Pfadnamen der Dateien, die diese Zeile enthalten, und führt rm -f
sie dann stapelweise aus.
Die verwendeten Flaggen grep
sind
-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 „ -i
with“ grep
, da dadurch auch Dateien gelöscht würden, die Zeilen wie KEY = 0
und kEY = 0
usw. enthalten, und Sie haben nichts zu diesen Groß-/Kleinschreibungsunterschieden gesagt.
Möchten Sie, dass der find
Befehl auf ein bestimmtes Dateinamensuffix beschränkt wird, wie etwa .ext
, dann verwenden Sie -name '*.ext'
im find
Befehl vor der Ausführung von grep
. Beispiel:
find . -name '*.ext' -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +