#!/bin/sh # change any uppercase letters in file and directory # names in the current directory and below. # License: LGPLv2 # note filenames with \1 or \n will cause problems # note this is still much slower than it could be, # as there is a separate mv executed for each file/dir. # It would be much more efficient to pass the output # of this to a python script for e.g. that does the rename find -depth '(' -type f -o -type d ')' | env LC_ALL=C grep -E "/[^/]*[A-Z]+[^/]*$" | #only process upcase names sed -e ' { #escape any chars that could cause problems #s/\([]"{}\$]\)/\\\1/g #keep orig path in hold space h #put basename in pattern space s/.*\/\([^/]*$\)/\1/ #lowercase basename y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ #exchange pattern and hold space x #format mv args 1 s/\(.*\/\)\([^/]*$\)/\1\2\1/ #format mv args 2 G }' | tr -d '\n' | #format mv args 3 tr '' '\0' | #format mv args 4 xargs -r0 -n2 mv #execute mv (CommandList children: [ (Pipeline children: [ (C {(find)} {(-depth)} {(EscapedLiteralPart token:)} {(-type)} {(f)} {(-o)} {(-type)} {(d)} {(EscapedLiteralPart token:)} ) (SimpleCommand words: [{(grep)} {(-E)} {(DQ ("/[^/]*[A-Z]+[^/]*") (Lit_Other "$"))}] more_env: [(env_pair name:LC_ALL val:{(C)} spids:[52])] ) (C {(sed)} {(-e)} { (SQ <"\n"> <"{\n"> <" #escape any chars that could cause problems\n"> <" #s/\\([]\"{}\\$]\\)/\\\\\\1/g\n"> <"\n"> <" #keep orig path in hold space\n"> <" h\n"> <"\n"> <" #put basename in pattern space\n"> <" s/.*\\/\\([^/]*$\\)/\\1\u0001/\n"> <"\n"> <" #lowercase basename\n"> <" y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/\n"> <"\n"> <" #exchange pattern and hold space\n"> <" x\n"> <"\n"> <" #format mv args 1\n"> <" s/\\(.*\\/\\)\\([^/]*$\\)/\\1\\2\u0001\\1/\n"> <"\n"> <" #format mv args 2\n"> <" G\n"> <"}"> ) } ) (C {(tr)} {(-d)} {(SQ <"\\n">)}) (C {(tr)} {(SQ <"\u0001">)} {(SQ <"\\0">)}) (C {(xargs)} {(-r0)} {(-n2)} {(mv)}) ] negated: False ) ] )