Als alternativer Ansatz, benötigen Sie keine externen Programme wie rename
, basename
usw. - es können alle innerhalb behandelt werden bash
Parameter Expansion: -
find SourceDir ... | while read -r f; do mv "$f" "TargetDir/$"; done
Die Erweiterung ist etwas schwer zu folgen, also passiert Folgendes: -
- Die zu verschiebenden Dateien werden mit gefunden
find
. - Jeder Dateiname wird nacheinander gelesen
$f
. - Der
read -r
Parameter und die doppelten Anführungszeichen um die Erweiterungen behandeln seltsame Namen, einschließlich Leerzeichen in den Dateinamen. - Der
mv
Befehl verschiebt Namen wie a/b/c
zu TargetDir/a_b_c
. - Die Zielerweiterung ersetzt jedes
/
by _
, sie ist jedoch entmutigend, da sie /
Teil der Substitutionssyntax ist. - Die allgemeine Form ist
$
, die die erste Instanz von old
by new
in der Erweiterung ersetzt. - Die Form, die hier benötigt wird
$
, ist die, die jede Instanz old
von new
in der Erweiterung ersetzt. - Um
/
Teil des alten Strings zu sein, muss dieser als \/
Escape-Code maskiert werden. Daher ist das eher undeutlich $
: Der erste Befehl /
führt die Substitutionssyntax ein, der zweite /
gibt jeden ein, der dritte (Escape-Code) /
ist der alte und der letzte String /
die neue Zeichenfolge ( _
).
Ich sehe diese Form der Erweiterung nicht oft in Skripten, aber es lohnt sich zu wissen, da sie manchmal sehr nützlich sein kann.
Es gibt einige Dateinamen, die dies zerstören (eingebettete neue Zeilenzeichen und führende oder nachgestellte Leerzeichen), wobei letztere auf zwei Arten möglich ist: -
- Verwenden Sie
read -r
statt read -r f
und verwenden Sie REPLY
statt f
. - Verwenden Sie
while f="$(line)"
statt read -r f
.
Letzteres ist sauberer, verwendet jedoch das externe Programm line
, das möglicherweise nicht auf allen Systemen verfügbar ist, obwohl es als Funktion codiert werden kann:
line() { read -r; r=$?; echo "$REPLY"; return $r; }