1

I want to rename several hundred files whose names are formatted as follows:

A Study in Scarlet - Arthur Conan Doyle.mobi
Anvil of Stars - Greg Bear.mobi
City and the Stars, The - Arthur C. Clarke.mobi

After renaming I want to reach this naming scheme:

Arthur Conan Doyle - A Study in Scarlett.mobi
Greg Bear - Avil of Stars.mobi
Arthur C. Clarke - City and the Stars, The.mobi

A bonus would be to remove all irregular characters from the name, as there are:

  1. _ [underscores] to replace by blank
  2. %20 to replace by blank
  3. [] to replace with rounded ones ()
Kevin Bowen
  • 19,615
  • 55
  • 79
  • 83
  • 1
    For ways to accomplish this with a GUI, see http://askubuntu.com/questions/511862/an-ubuntu-linux-alternative-of-bulk-rename-utility-for-windows –  May 12 '16 at 01:19
  • 1
    ^ also http://askubuntu.com/questions/10607/what-mass-file-renaming-tools-are-available –  May 12 '16 at 01:43

2 Answers2

3

I wrote a small bash script to do the job.

#!/bin/bash

# Variables
extension='mobi'
report='report.log'    

if [ -f $report ];
then
    rm -rf $report
fi

echo $'renaming files . . .\n'

for filename in *.$extension
do
    temp=$(echo $filename | tr '_' ' ' | tr '%20' ' ' | tr '[]' '()' | tr -s ' ' | sed 's/\.[^.]*$//' )

    part1=$(echo $temp | cut -f1 -d-)
    part2=$(echo $temp | cut -f2 -d-)
    new_filename=$(echo "${part2#?} - ${part1%?}.$extension")
    echo $(mv -v "$filename" "$new_filename") | tee -a $report
    if [ $? -ne 0 ]; then
        echo $'\n\nScript FAILED'
        exit 1
    fi
done

echo $'\n\nScript SUCCESSFUL'
exit 0

Create a .bsh file inside the directory in which your .mobi files are stored and paste the above code :

Open a Terminal with Ctrl + Alt + T and navigate to the directory in which your script is stored :

cd /path/to/directory/

To change the permissions of the script :

chmod +x <filename>.bsh

To execute the script :

bash <filename>.bsh

If for some reason the mv fails you will receive an error 'Script FAILED', otherwise you'll get 'Script SUCCESSFUL'.


Explanation

tr '_' ' ' replace underscores with whitespace

tr '%20' ' ' replace %20 with whitespace

tr '[]' '()' replace square brackets with parentheses

tr -s ' ' replace multiple spaces with one

sed 's/\.[^.]*$//' extracts only the name of the file without the extension

${string#?} remove first character of a string

${string%?} remove last character of a string

mv -v this will show in the terminal which files are being moved. -v stands for verbose.

tee -a changelog.log By default tee command reads from standard input, and writes to standard output and files. -a stands for append.

if [ $? -ne 0 ] checks if the previous command was successful.

report.log stores the previous and latest name of each file.


Note

The script assumes that the filename contains only one dash -

efthialex
  • 3,831
0

You could use find, xargs, and prename to do this. Read their man pages.

prename applies a Perl "regular expression" to file names, and find and xargs are used to deal with filenames containing Space characters.

I can offer:

find . -type f -iname '*.mobi' -print0 | \
    xargs -0 prename -v -n 's%^(.*/)(.*)( - )(.*)\.mobi%$1$4$3$2.mobi%'

And, it worked for me:

  $ find . -maxdepth 1 -name '*.mobi' -print0 | xargs -0 prename -n -v 's%^(.*/)(.*)( - )(.*)\.mobi%$1$4$3$2.mobi%' 
./A Study in Scarlet - Arthur Conan Doyle.mobi renamed as ./Arthur Conan Doyle - A Study in Scarlet.mobi

You could use additional executions of prename to change your other funny characters. Be sure to read man perlre to learn about Perl Regular Expressions. If you haven't used regular expressions before, a quick-start introduction is available in man perlrequick, and a longer tutorial introduction is available in man perlretut.

waltinator
  • 36,399