Entfernen Sie alle Dateien, deren Inhalt KEIN Muster enthält

Entfernen Sie alle Dateien, deren Inhalt KEIN Muster enthält

Wie entferne ich alle Dateien, die einen bestimmten Text nicht enthalten?

Ich verstehe die Lösung zum Entfernen von Dateien mit einem angegebenen Text, aber ich muss Dateien entfernen, die KEIN angegebenes Muster enthalten.

Der folgende Befehl erstellt eine Liste von Dateien, die „successful run“ nicht enthalten:

grep -c "successful run" *.out | grep -v ":1" > err.txt

Ich möchte diese Dateien direkt löschen.

Antwort1

Ihr ursprünglicher Ansatz zur Identifizierung geeigneter Dateien

grep -c "successful run" *.out | grep -v ":1"

ist fehlerhaft. Hauptbedenken:

  • Was passiert, wenn in einer Datei zwei oder mehr übereinstimmende Zeilen vorhanden sind? grep ":0"scheint besser auf die Bedingung im Titel Ihrer Frage zu passen („Dateien, die kein Muster enthalten“).
  • Was ist, wenn :1(oder :0) im Dateinamen vorkommt? Das grep ':0$'scheint sogar noch besser zu sein.
  • Was passiert, wenn in einem der vom ersten übergebenen Dateinamen ein Zeilenumbruchzeichen vorhanden ist grep?

Ich sage, verlassen Sie sich nicht auf grep -c; verlassen Sie sich auf den Beendigungsstatus, grepder vorliegt, 1wenn keine Zeilen ausgewählt wurden.

for f in *.out; do
   [ -f "$f" ] && {
      grep -q -- "successful run" "$f"
      [ "$?" -eq 1 ] && rm -i -- "$f"
   }
done

Anmerkungen:

  • [ -f "$f" ] && …lässt nicht grepdie Arbeit mit passenden Verzeichnissen, FIFOs usw. zu *.out; nur mit regulären Dateien.
  • Die Bedeutung und Wichtigkeit von --wird erklärtHier. Wenn eine Datei mit einem Namen vorhanden ist, der mit beginnt -, kann sie für eine Option gehalten werden. Eine andere Möglichkeit, mit diesem Problem umzugehen, ist . Auf diese Weise beginnt for f in ./*.out; do …jede Erweiterung mit und kann nicht mit beginnen .$f./-
  • Ich habe rm -inur für alle Fälle verwendet. Nachdem Sie die Lösung getestet haben, möchten Sie es vielleicht weglassen -i.
  • grep … || rm …ist schlimmer. Wenn ein echter Fehler auftritt (z. B. Zugriff verweigert), ist der Exit-Status grepgrößer als 1; dann möchten Sie die Datei wahrscheinlich nicht entfernen. Meine Lösung prüft, ob der Exit-Status genau ist 1.
  • Ihr Originalcode wandert nicht in Unterverzeichnisse, meiner auch nicht. Wenn Sie Rekursion wünschen, ist eine Shell, die dies unterstützt (z. B. Bash mit shopt -s globstarund **), oder eine auf basierende Lösung findnützlich.

Antwort2

Wenn Sie davon ausgehen, dass Ihre Dateien entweder einen einzigen „erfolgreichen Lauf“ aufweisen oder keinen, gilt Folgendes:

Um die passenden Dateien zu finden, können Sie Folgendes tun:

grep -l "successful run" *.out > err.txt

um sie zu finden und zu entfernen:

grep -l "successful run" *.out | xargs rm

Um die Dateien ohne Übereinstimmung zu finden, gehen Sie folgendermaßen vor:

grep -vl "successful run" *.out > ok.txt

um sie zu finden und zu entfernen:

grep -vl "successful run" *.out | xargs rm

Die Flaggen bedeuten:

-l lists the files with matches
-v/--invert-match inverts the matching logic

verwandte Informationen