Wie man eine Reihe von Dateien wie file01.txt, file02.txt ... file85.txt 'rmt' oder 'mv'

23

Angenommen, ich habe eine Reihe von Dateien mit folgendem Namen:

file01.txt file02.txt file03.txt ... file20.txt

und ich möchte einen Befehl für einen Bereich dieser Dateien ausführen.

Ich weiß, ob ich von 'file05.txt' zu 'file09.txt' wechseln möchte. Ich kann:

rm file0[5-9].txt

aber wie kann ich einen Bereich von file08.txt bis file13.txt "rm"? Ich habe diesen Code ausprobiert

rm file[08-13].txt

und es funktioniert nicht. Ich könnte diesen Befehl ausführen:

rm file0[89].txt file1[0-3].txt

aber ich würde gerne wissen, ob ich dies mit nur einem weiteren verfeinerten Argument für "rm" tun kann, wenn es möglich ist.


quelle
Eine fast identische Frage wurde hier beantwortet: stackoverflow.com/questions/25049411/…
Arielf

Antworten:

38

Sie benötigen eine Klammererweiterung von bash:

rm file{08..13}.txt

Dadurch werden die Dateien entfernt file08, file13und es wird eine Fehlermeldung angezeigt, wenn eine Datei fehlt.

Stellen Sie den Bereich so ein, dass er Ihren Anforderungen entspricht.


Das Problem mit dem Globbing-Operator []besteht darin, dass jedes Zeichen / jede Ziffer darin als einzelnes Token behandelt wird und daher nur die Bereichsangabe mit einzelnen Ziffern unterstützt wird.

Wenn Sie darauf bestehen [], können Sie dieses ziemlich hässliche Muster verwenden, um Folgendes file08zu erreichen file13:

rm file0[8-9].txt file1[0-3].txt
heemayl
quelle
5
Klammer-Erweiterung ist auch nützlich mit Kommas, wie für mv foo.{txt,md}odercp foo.txt{,.bak}
Kos
2

Einige Shells, wie Ubuntus Standard /bin/sh(der ist dash) oder mkshnicht geschweifte Klammern, oder ksh- geschweifte Klammern können keine gepolsterten Nullen verwenden:

$ ksh -c 'echo {05..13}'
5 6 7 8 9 10 11 12 13

In solchen Fällen können wir printfden nummerierten Teil des Dateinamens formatieren und eine while-Schleife verwenden, um das Verhalten einer c-ähnlichen Schleife zu implementieren (Anmerkung zum Ersetzen echodurch rmoder was auch immer Sie wollen):

$ i=5; while [ "$i" -le 10 ]; do num=$(printf "%.2d" "$i" ); echo "file$num.txt";i=$(($i+1)); done
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

Und das ist ziemlich tragbar - arbeitet mit dash, ksh, mksh, auch bash. Im Falle von kshund können bashwir auch c-style for loop syntax (but not in case ofmksh ordash verwenden`):

$ ksh -c 'for((i=5;i<11;i++)); do num=$(printf "%.2d" "$i" ); echo "file$num.txt";done'             
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

Beachten Sie, dass in diesem bashFall printfdas Drucken in eine Variable unterstützt wird und daher printf -v num "%.2d" "$i"anstelle der Befehlsersetzung die Option verwendet werden kann.

Sergiy Kolodyazhnyy
quelle