Find the answer to your Linux question:
Results 1 to 9 of 9
I need a either a script or perl script that will allow me to mass rename files, folders, and sub folders. I need to replace special chars in the current ...
  1. #1
    Just Joined!
    Join Date
    Sep 2009
    Posts
    5

    Need a script to mass rename files recursively



    I need a either a script or perl script that will allow me to mass rename files, folders, and sub folders. I need to replace special chars in the current file names with underscores. I was able to make this happen in a single directory, but not recursively. Any help would be wonderful.

    Here is what does it in a single directory.

    for file in *
    do
    mv "$file" $(echo "$file" | sed 's/[^A-Za-z0-9_.]/_/g')
    done

  2. #2
    Just Joined!
    Join Date
    Aug 2009
    Posts
    76
    I don't know enough about bash to write a good script for you, but couldnt you run a command like this?

    ls -R | grep mp3

    And grab the files with a certain extension and pass it off to sed somehow?

    If learning how to do this via bash isnt important to you you COULD always take the easy way out and download krename (QT/KDE) or pyRename (GTK/Gnome)

    Both are really excellent programs

  3. #3
    Just Joined!
    Join Date
    Sep 2009
    Posts
    5
    "I don't know enough about bash to write a good script for you, but couldnt you run a command like this?

    ls -R | grep mp3"

    Thanks for the reply. But that doesn't quite get me what I need. That would give me all the files with mp3 in them. But what I need is something that will find special characters, then replace those characters with underscores.

    I will check out the programs you named.

    Thanks

  4. #4
    Linux Guru
    Join Date
    Nov 2007
    Location
    Córdoba (Spain)
    Posts
    1,513
    Quote Originally Posted by dnielsen78 View Post
    I need a either a script or perl script that will allow me to mass rename files, folders, and sub folders. I need to replace special chars in the current file names with underscores. I was able to make this happen in a single directory, but not recursively. Any help would be wonderful.

    Here is what does it in a single directory.

    for file in *
    do
    mv "$file" $(echo "$file" | sed 's/[^A-Za-z0-9_.]/_/g')
    done
    Code:
    find . -printf '%f\n' | while read file; do
      newfile=$(echo "$file" | sed 's/[^A-Za-z0-9_.]/_/g')
      if [ ! "$newfile" == "$file" ]; then
        echo mv "$file" "$newfile"
      fi
    done
    Untested.

    If you like the output, remove the "echo" in front of the "mv" to do the real work.

  5. #5
    Just Joined!
    Join Date
    Sep 2009
    Posts
    5
    I tried the code you posted and I get an error on line 7: syntax error: unexpected end of file.

  6. #6
    Linux Guru
    Join Date
    Nov 2007
    Location
    Córdoba (Spain)
    Posts
    1,513
    Are you sure you didn't miss a closing quotation mark, "done", "fi", parentheses or bracket anywhere?

    I just tested it (copy/paste) and it seems to work ok.

  7. #7
    Just Joined!
    Join Date
    Sep 2009
    Posts
    5
    o.k I must of missed something. Now it appears to be working with one small issue. It doesn't seem to want to go down recursively though the directory. I get the following error.

    mv: cannot stat `3-2-1': No such file or directory
    mv: cannot stat `1-2-3.txt': No such file or directory
    mv: cannot stat `1-2-3-4': No such file or directory
    mv: cannot stat `2-3-4.txt': No such file or directory

    Here is what I have as a test

    sled:~/renametest/1_2_3_4 # pwd
    /root/renametest/1_2_3_4
    sled:~/renametest/1_2_3_4 # ls -R
    .:
    1-2-3-4 1-2-3.txt 2-3-4.txt 3-2-1

    ./1-2-3-4:

    ./3-2-1:
    sled:~/renametest/1_2_3_4 #


    Thanks for any help, I really really appreciate this.

  8. #8
    Linux Guru
    Join Date
    Nov 2007
    Location
    Córdoba (Spain)
    Posts
    1,513
    Ops, I chose the wrong print format specifier, %p should work I guess. I also added some code not to touch the directory names, if you want to change them as well you will have to do so in a separate step anyway, because otherwise no one can guarantee that the paths will be consistent during all the process.

    Code:
    find . -type f -printf '%p\n' | while read file; do
      oldfile=$(basename "$file")
      newfile=$(echo "$oldfile" | sed 's/[^A-Za-z0-9_.]/_/g')
      if [ ! "$newfile" == "$oldfile" ]; then
        echo mv "$file" "${file%$oldfile}$newfile"
      fi
    done

  9. #9
    Just Joined!
    Join Date
    Sep 2009
    Posts
    5
    Nice it works great!

    Thanks so much for helping me out!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •