#!/bin/bash # Replaces odd characters in filenames and directories with an underline # When there are more consecutive odd characters what would result in ____ sth like this, it collates to a single underline. # When the new unixified filename is already taken, a counted suffix will be added before an eventuel period in the filename, otherwise just append. # Will never overwrite a file. # usage: unixify.sh path [--doit] # path The file to unixify, can be file or folder. export IFS=$'\n' rootdir=$1 really_do_it=$2 function usage { echo "usage: unixify.sh path [--doit]" echo "" echo " path - The file to unixify, can be file or folder" echo " --doit - dry run unless specified" echo "" echo "Replaces odd characters in filenames and directories with an underline" echo "When the new unixified filename is already taken, a counted suffix will be" echo "added before an eventual dot in the filename, otherwise just appended." echo "Will never overwrite a file." exit 255 } function unixify_string { local retval=$(echo $1 | gsed -e 's/[^A-Za-z0-9#./_-]/_/g') # replace everything else with _ retval=$(echo $retval | gsed -e 's/\.\{2,\}/\./g') # replace >1 consecutive . with one . retval=$(echo $retval | gsed -e 's/_\{2,\}/_/g') # replace >1 consecutive _ with one _ echo $retval } function unixify_filename { fname_full=$1 current_dir=$(dirname $fname_full) current_file=$(basename $fname_full) fname_new=$(unixify_string $current_file) # unixify #echo "$fname_full" if [ "$current_file" != "$fname_new" ]; then { #any changes been needed? count=1 while [ -e $current_dir/$fname_new ]; do { #new filename already taken? #echo file exists: $current_dir/$fname_new; #add suffix before any dot, if no dot just append if [[ "$fname_new" =~ \. ]]; then { fname_new=$(echo $fname_new | sed -e "s/\./_$count\./g") }; else { fname_new=$fname_new"_$count" }; fi count=$(($count + 1)) }; done cmd="mv '$fname_full' '$current_dir/$fname_new'" echo $cmd if [ "$really_do_it" == "--doit" ]; then { eval $cmd }; fi }; fi } function unixify_path_contents { fpath=$1 for i in $(find $fpath -mindepth 1 -maxdepth 1 | sort); do { unixify_filename $i; }; done for i in $(find $fpath -mindepth 1 -maxdepth 1 -type d | sort); do { unixify_path_contents $i; }; done } if [ -z "$rootdir" ]; then { usage }; fi if [ ! -e $rootdir ]; then { echo "$rootdir - no such file or dir" exit 255 }; fi if [ "$really_do_it" != "--doit" ]; then { echo "Dry run. Not really doing anything." }; fi unixify_path_contents $rootdir