Wie entferne ich mehrere Dateien mit einem gemeinsamen Präfix und Suffix?

21

Ich habe viele Dateien mit dem Namen

sequence_1_0001.jpg  
sequence_1_0002.jpg  
sequence_1_0003.jpg  
...

und Dateien mit dem Namen

sequence_1_0001.hmf  
sequence_1_0002.hmf  
sequence_1_0003.hmf  
...

und Dateien mit dem Namen

sequence_2_0001.jpg  
sequence_2_0002.jpg  
sequence_2_0003.jpg  
...

und

sequence_2_0001.hmf  
sequence_2_0002.hmf  
sequence_2_0003.hmf  
...

Ich möchte nur die Dateien entfernen, die mit 'sequence_1' beginnen und mit '.hmf' enden, aber ich möchte sie nicht einzeln entfernen, da es Tausende von Dateien gibt. Wie kann ich dem Befehl rm angeben, dass alle Einträge entfernt werden sollen, die mit dem Präfix 'sequence_1' beginnen und mit '.hmf' enden?

Ich arbeite derzeit mit einem RedHat Linux-System, aber ich würde gerne wissen, wie das auch bei anderen Distributionen funktioniert.

Paul
quelle

Antworten:

28
rm sequence_1*.hmf

Entfernt Dateien, die mit beginnen sequence_1und mit enden .hmf.


Globbing ist der Prozess, bei dem Ihre Shell ein Muster aufnimmt und es in eine Liste von Dateinamen erweitert, die mit diesem Muster übereinstimmen. Verwechseln Sie es nicht mit regulären Ausdrücken, die anders sind. Wenn Sie die meiste Zeit in verbringen bash, hat das Wooledge-Wiki eine gute Seite zum Thema Globbing (Pfadnamenerweiterung) . Wenn Sie maximale Portabilität wünschen, sollten Sie stattdessen auch die POSIX-Spezifikation zum Mustervergleich lesen .


In dem unwahrscheinlichen Fall, dass Sie auf den Fehler "Argumentliste zu lang" stoßen , können Sie sich BashFAQ 95 ansehen , das dies behebt . Die einfachste Problemumgehung besteht darin, das Glob-Muster in mehrere kleinere Blöcke aufzuteilen, bis der Fehler behoben ist. In Ihrem Fall könnten Sie wahrscheinlich davonkommen, die Übereinstimmung durch die Präfix-Ziffern 0 bis 9 wie folgt zu teilen:

for c in {0..9}; do rm sequence_1_"$c"*.hmf; done
rm sequence_1*.hmf  # catch-all case
jw013
quelle
Dies ist eine sehr clevere Arbeit, um den Fehler "Argumentliste zu lang" zu umgehen. In meinem Fall habe ich zwanzigtausend Dateien, also müsste ich wohl eine for-Schleife von 0, .., 20 verwenden. Recht?
Paul
@Paul Richtig, teilen Sie die Liste einfach in so viele Teile auf, wie Sie benötigen, obwohl der findAnsatz irgendwann einfacher wird, als zu raten und zu überprüfen.
JW013
14

Obwohl die Antwort von jw013 richtig ist, kann dieser Befehl fehlschlagen, wenn Sie Tausende von Übereinstimmungen haben: Die rm sequence_1_0001.hmf sequence_1_0002.hmf ...von der Shell generierte erweiterte Befehlszeile ist möglicherweise einfach zu groß.

Wie Dom vorgeschlagen hat, können Sie die -deleteOption auch mit findfolgenden Komponenten verwenden :

find . -maxdepth 1 -type f -name 'sequence_1*.hmf' -delete

Beide -maxdepthund -delete, obwohl sie nicht im POSIX-Standard enthalten sind, sind bei findImplementierungen in freier Wildbahn ziemlich verbreitet . Linux-Distributionen verwenden im Allgemeinen GNU find, das diese Optionen auf jeden Fall unterstützt.

Nutzlos
quelle
2
Wenn Sie können, verwenden Sie die Option -delete für die Suche, es wird nicht für jede Datei Gabelung ...
Dom
Hinzugefügt, Prost. Es sieht so aus, als ob -deletees auf neueren GNU- und BSD-Systemen unterstützt werden sollte, während -print0es sich nur um GNU handelt. Es ist also wahrscheinlich auch portabler (obwohl es für das OP keinen Unterschied machen sollte).
Nutzlos
Zumindest OS X's find hat -print0, aber es ist nicht in POSIX enthalten.
Lri
5
rm sequence_1_{0000..0999}.hmf
rm sequence_1_{1000..1999}.hmf
rm sequence_1_{2000..2999}.hmf
...

würde auch in Bash funktionieren.

Benutzer unbekannt
quelle
Die Klammererweiterung erfordert bash, und die null aufgefüllte Form benötigt Version 4, glaube ich.
JW013