Ok, since your shell apparently doesn't have a basedir command, here's a script that uses find and nested for loops and doesn't need either basename or basedir: for D in `find topdir -type d -print | sort -r`; do (cd $D for F in *; do mv $F "`echo $F | sed -e 's/-/_/g'`"; done ) done I think that should do it -- note it will change the names from the deepest files to the topmost so you won't run into problems with the directory names. HTH --le