1

I have a script that is giving me some problems, I know that I have to re-do it recursively but am having some trouble. The script should rename all files and folders in a given folder by removing special characters like $-,)(! and replacing " " with "_"

Here is the piece I need to re-do:

# Rename directories
find "$ORIG_DIR" -name "*" -type d| while read dname
do
    NEW_DIR=`echo "$dname" |sed -E 's/^[ \t]*//g; s/[ \t]*$//g; s/\./_/g; s/\,/_/g; s/ /_/g'`

        # Rename files
        find "$ORIG_DIR" -name "*" -type f | while read fname
        do
            NEW_FNAME=`echo "$fname" |sed -E 's/^[ \t]*//g; s/[ \t]*$//g; s/\./_/g; s/(.*)_/\1\./; s/\,/_/g; s/ /_/g'`
            if [ -e $NEW_FNAME ]
            then
                echo "$NEW_FNAME already exists. Not replacing $fname"
            else
                echo "Replacing $fname with $NEW_FNAME"
                mv "$fname" $NEW_FNAME
            fi
        done

    if [ -e $NEW_DIR ]
    then
        echo "$NEW_DIR already exists. Not replacing $dname"
    else
        echo "Replacing $dname with $NEW_DIR"
        mv "$dname" $NEW_DIR
    fi
done

END
3
  • Where do you run into troubles with this script? Do you get error messages, does it do something different than expected?
    – nohillside
    Jan 16 '14 at 22:54
  • The error message that I get in the end is that there is no such file or directory. This script also won't remove !,$-)(
    – Erick
    Jan 17 '14 at 15:54
  • Well, one problem with the script is that both find commands will always travers the whole directory tree (replace the functionality inside by echo statements to see what's going on).
    – nohillside
    Jan 17 '14 at 16:00
1

Untested

find . -depth -print0 |
while IFS= read -d '' -r file; do
    dir=$(dirname "$file")
    base=$(basename "$file") 
    base=${base//[[:space:]]/_}         # change whitespace to underscores
    base=${base//[^[:alnum:]_.]/}       # delete any chars not alphanumeric _ .
    newname="$dir/$base"
    if [[ -e $newname ]]; then
        echo "'$newname' exists, not renaming '$file'"
    else
        echo mv "$file" "$newname"
    fi
done

If it looks OK, remove the "echo"

The key here is the "-depth" option to find. It will emit "./sub dir/file name" before "./sub dir". Otherwise if "./sub dir" is renamed to "./subdir", then you'll get a 'file not found' error when the while loops gets to "./sub dir/file name". Also, it means you don't need different logic for directories.

The "-print0" option to find and the busy-ness around the read command are to ensure filenames with spaces are handled properly.

1
  • This is a good step but it is going too far. It will remove the "." before the file extension which is no good. Also I do want to keep any underscores and have spaces replaced by underscores. Secondly I named the folder in the command, i.e. Folder A, but the script hit all of the folders in the directory containing Folder A.
    – Erick
    Jan 17 '14 at 15:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .