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!' {} +