Chci malá písmena v názvu každého adresáře v adresáři. Pomocí jakých příkazů to mohu provést?
Přijatá odpověď:
Všechny adresáře na jedné úrovni, nebo rekurzivně?
Zsh
Na jedné úrovni:
autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'
Rekurzivně:
zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'
Vysvětlení:zmv
přejmenuje soubory odpovídající vzoru podle daného nahrazujícího textu. -o-i
předá -i
možnost pro každý mv
příkaz pod kapotou (viz níže). V nahrazujícím textu $1
, $2
, atd., jsou po sobě jdoucí skupiny v závorkách ve vzoru. **
znamená všechny (pod)*adresáře, rekurzivně. Poslední (/)
není skupina v závorkách, ale kvalifikátor glob, což znamená, že odpovídá pouze adresářům. ${2:l}
převede $2
na malá písmena.
Přenosné
Na jedné úrovni:
for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done
Poslední /
omezuje shodu na adresáře a mv -i
vyžádá si potvrzení v případě kolize. Odstraňte -i
pro přepsání v případě kolize a použijte yes n | for …
. abyste nebyli vyzváni a neprováděli žádné přejmenování, které by kolidovalo.
Rekurzivně:
find root/* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} ;
Použití -depth
zajišťuje, že hluboce vnořené adresáře jsou zpracovány dříve než jejich předkové. Zpracování názvu závisí na přítomnosti /
; pokud chcete volat operaci v aktuálním adresáři, použijte ./*
(přizpůsobení skriptu shellu, aby se vyrovnal s .
nebo *
je ponecháno jako cvičení pro čtenáře).
Přejmenování Perlu
Zde používám skript pro přejmenování Perl, který Debian a Ubuntu dodávají jako /usr/bin/prename
(obvykle dostupné jako rename
také). Na jedné úrovni:
rename 's!/([^/]*/?)$!L/$1!' root/*/
Rekurzivně, s bash ≥4 nebo zsh:
shopt -s globstar # only in bash
rename 's!/([^/]*/?)$!L/$1!' root/**/*/
Rekurzivně, přenosně:
find root -depth -type d -exec rename -n 's!/([^/]*/?)$!L/$1!' {} +