Ich möchte den Namen jedes Verzeichnisses unter einem Verzeichnis klein schreiben. Mit welchen Befehlen kann ich das machen?
Akzeptierte Antwort:
Alle Verzeichnisse auf einer Ebene oder rekursiv?
Schsch
Auf einer Ebene:
autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'
Rekursiv:
zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'
Erläuterungen:zmv benennt Dateien, die einem Muster entsprechen, gemäß dem angegebenen Ersetzungstext um. -o-i übergibt das -i Option zu jedem mv Befehl unter der Haube (siehe unten). Im Ersetzungstext $1 , $2 usw. sind die aufeinanderfolgenden eingeklammerten Gruppen im Muster. ** bedeutet alle (Unter-)*Verzeichnisse, rekursiv. Der letzte (/) ist keine Gruppe in Klammern, sondern ein Glob-Qualifizierer, der bedeutet, dass nur Verzeichnisse abgeglichen werden. ${2:l} konvertiert $2 in Kleinbuchstaben.
Tragbar
Auf einer Ebene:
for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done
Der letzte / schränkt den Abgleich auf Verzeichnisse ein und mv -i fordert im Falle einer Kollision eine Bestätigung an. Entfernen Sie das -i um im Fall einer Kollision zu überschreiben, und verwenden Sie yes n | for … . nicht aufgefordert zu werden und keine Umbenennungen durchzuführen, die kollidieren würden.
Rekursiv:
find root/* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} ;
Die Verwendung von -depth stellt sicher, dass tief verschachtelte Verzeichnisse vor ihren Vorfahren verarbeitet werden. Die Namensverarbeitung beruht darauf, dass ein / vorhanden ist; Wenn Sie Operate im aktuellen Verzeichnis aufrufen möchten, verwenden Sie ./* (Anpassen des Shell-Skripts, um mit . fertig zu werden oder * bleibt dem Leser als Übung überlassen).
Perl-Umbenennung
Hier verwende ich das Perl-Umbenennungsskript, das Debian und Ubuntu als /usr/bin/prename ausliefern (normalerweise verfügbar als rename auch). Auf einer Ebene:
rename 's!/([^/]*/?)$!L/$1!' root/*/
Rekursiv, mit bash ≥4 oder zsh:
shopt -s globstar # only in bash
rename 's!/([^/]*/?)$!L/$1!' root/**/*/
Rekursiv, portabel:
find root -depth -type d -exec rename -n 's!/([^/]*/?)$!L/$1!' {} +