Search code examples
bashloopsrename

mass rename brings errors


I have got the following files in current dir:

file_73tyd7d.jpg
file_e8djuh.jpeg
file_eidie8d.jpg
file_iadiijj.jpg

I want:

0.jpg
1.jpeg
2.jpg
3.jpg

I first do:

NB=0;for FILE in `ls`;do echo mv "${FILE}" "${NB}.${FILE#*.*}";((NB=NB+1));done

or

NB=0;for FILE in `ls`;do echo mv "${FILE}" "${NB}"."${FILE#*.*}";((NB=NB+1));done

output:

file_73tyd7d.jpg 0.jpg  -> why is that? 
mv file_e8djuh.jpeg 1.jpeg
mv file_eidie8d.jpg 2.jpg
mv file_iadiijj.jpg 3.jpg

apart from the first file, it looks good. now I do:

NB=0;for FILE in `ls`;do mv "${FILE}" "${NB}.${FILE#*.*}";((NB=NB+1));done

and I have got the following error:

mv: cannot stat ''$'\033''[H'$'\033''[2J'$'\033''[3J'$'\033''[0m'$'\033''[01;35mfile_73tyd7d.jpg'$'\033''[0m': No such file or directory

mv: cannot stat ''$'\033''[01;35mfile_e8djuh.jpeg'$'\033''[0m': No such file or directory

mv: cannot stat ''$'\033''[01;35mfile_eidie8d.jpg'$'\033''[0m': No such file or directory

mv: cannot stat ''$'\033''[01;35mfile_iadiijj.jpg'$'\033''[0m': No such file or directory

Solution

  • For this task, do not use ls at all. ls is supposed to be used interactively (See Why you shouldn't parse the output of ls). Also, do not use all-caps names for your own variable names (See Correct Bash and shell script variable capitalization). Your script should have been written something like this:

    #!/bin/bash
    
    nb=0
    for file in *; do
        echo mv -i -- "$file" "$((nb++)).${file##*.}"
    done