Ich weiß, dass ich in Bash mithilfe eines Sternchens ein Platzhalterzeichen verwenden kann, um Dateien mit Namen eines bestimmten Formats zu extrahieren, und zwar etwa so:
$ ls
a01 a02 a03 a04 a05 a06 a07 a08 a09 b01 b02 b03 b04 b05 b06 b07 b08 b09
$ ls a*
a01 a02 a03 a04 a05 a06 a07 a08 a09
$ ls b*
b01 b02 b03 b04 b05 b06 b07 b08 b09
Wenn ich jedoch beispielsweise alle Dateien, die mit a beginnen, in ein Verzeichnis namens verschieben a
und alle Dateien, die mit b beginnen, in ein Verzeichnis namens verschieben möchte b
, wie mache ich das mit einem Befehl?
Können Sie so etwas machen:
$ mv *0* */
Aber irgendwie auf das erste Sternchen im Move-To-Argument verweisen?
Antwort1
Ein Befehl, eine Zeile:
for n in *;do [ -f "$n" ] && case "$n" in a*) mv "$n" a/;; b*) mv "$n" b/;; esac; done
Alternativ könnte man den Namen des Verzeichnisses aus dem Dateinamen ableiten, aber das habe ich zunächst nicht gezeigt, da ich davon ausging, dass es eine längere Zeile wäre. Die Anweisung in der Schleife wäre beispielsweise (erster Versuch):
d=$(echo "$n" | sed -e 's/^\(.\).*/\1/'); [ -f "$n" ] && mv "$n" $d/
würde den ersten Buchstaben des angegebenen Dateinamens verwenden, um den Verzeichnisnamen zu erhalten. Vergleichen Sie mit
[ -f "$n" ] && case "$n" in a*) mv "$n" a/;; *b) mv "$n" b/;; esac
für die Case-Anweisung. Eigentlich nicht viel länger, aber schwieriger spontan einzutippen. Da bash
erwähnt wird, kann man die Teilstring-Syntax verwenden, ${parameter:offset:length}
um diese Zeile zu verkürzen:
d=${n:0:1}; [ -f "$n" ] && mv "$n" $d/
oder
[ -f "$n" ] && mv "$n" ${n:0:1}/
(Ich erinnere mich, dass es sich dabei um eine Bash-Erweiterung handelte, und finde es nicht inPOSIX).
Zur eigentlichen Frage nach der Wiederverwendung von Platzhaltern: Das bezieht sich offenbar aufKlammererweiterung. Diese werden vor der Stelle erweitert, an der Sie sie benötigen. Zitat aus der Dokumentation:
Die Klammererweiterung wird durchgeführtVoralle anderen Erweiterungen und alle für andere Erweiterungen speziellen Zeichen bleiben im Ergebnis erhalten. Es iststreng textlich. Bash tutnichtWenden Sie eine syntaktische Interpretation auf den Kontext der Erweiterung oder den Text zwischen den Klammern an. Um Konflikte mit der Parametererweiterung zu vermeiden, wird die Zeichenfolge „${“ nicht für die Klammererweiterung in Betracht gezogen.