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.
Antworten:
Sie benötigen eine Klammererweiterung von
bash
:Dadurch werden die Dateien entfernt
file08
,file13
und 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 Folgendesfile08
zu erreichenfile13
:quelle
mv foo.{txt,md}
odercp foo.txt{,.bak}
Einige Shells, wie Ubuntus Standard
/bin/sh
(der istdash
) odermksh
nicht geschweifte Klammern, oderksh
- geschweifte Klammern können keine gepolsterten Nullen verwenden:In solchen Fällen können wir
printf
den nummerierten Teil des Dateinamens formatieren und eine while-Schleife verwenden, um das Verhalten einer c-ähnlichen Schleife zu implementieren (Anmerkung zum Ersetzenecho
durchrm
oder was auch immer Sie wollen):Und das ist ziemlich tragbar - arbeitet mit
dash
,ksh
,mksh
, auchbash
. Im Falle vonksh
und könnenbash
wir auchc-style for loop syntax (but not in case of
mkshor
dash verwenden`):Beachten Sie, dass in diesem
bash
Fallprintf
das Drucken in eine Variable unterstützt wird und daherprintf -v num "%.2d" "$i"
anstelle der Befehlsersetzung die Option verwendet werden kann.quelle