Search code examples
bashbatch-rename

Rename files ordered by date


I'm having trouble with this script:

#!/bin/bash
echo -n "Digit new name (no spaces and special chars!): "
read newname

echo -e "\n"

i=0

if test "$(ls -A | grep [.]jpg)"; then
    for f in "$(ls -Atr | grep [.]jpg)"; do
        let i=i+1
        #mv "$f" "$(printf "${newname}_%03d.jpg" "$i")"
        echo "$f renamed in: " $(printf "${newname}_%03d.jpg" "$i")
    done
    echo -e "\n\033[1;33;41m$i substituded!\033[0m\a"
else
    echo -e "\n\033[1;33;41mNothing was done!\033[0m\a"
fi
sleep 3

exit

My problem is to substitute all file but ordered by date (older first). On script above, I'm testing with echo and the result is all the list of files is renamed in one single files.


Solution

  • The problem is that you're quoting "$(ls -Atr | grep [.]jpg)" so you're getting just a long string with all the filenames.

    This would be a better attempt:

    #!/bin/bash
    read -p "Digit new name (no spaces and special chars!): " newname
    echo
    i=0
    if test "$(ls -A | grep [.]jpg)"; then
        while IFS= read -r f; do
            let i=i+1
            #mv "$f" "$(printf "${newname}_%03d.jpg" "$i")"
            echo "$f renamed in: " $(printf "${newname}_%03d.jpg" "$i")
        done < <(ls -Atr | grep [.]jpg)
        echo -e "\n\033[1;33;41m$i substituded!\033[0m\a"
    else
        echo -e "\n\033[1;33;41mNothing was done!\033[0m\a"
    fi
    

    Notice I'm using:

    read -p "Digit new name (no spaces and special chars!): " newname
    

    Instead of:

    echo -n "Digit new name (no spaces and special chars!): "
    read newname
    

    -p option is for that purpose and output the text in the standard error.


    Updated answer

    Here an enhanced method supporting also special chars:

    #!/bin/bash
    shopt -s nullglob
    read -p "Digit new name (no spaces and special chars!): " newname
    echo
    if test "$(ls -A | grep [.]jpg)"; then
        while read -r f; do
            ((i++))
            f=${f:1:((${#f}-2))} # remove the leading and trailing '
            f=${f//\\\"/\"}      # removed the \ before any embedded "
            f=$(echo -e "$f")    # interpret the escaped characters
            echo "$f renamed in: " $(printf "${newname}_%03d.jpg" "$i")
            #mv "$f" "$(printf "${newname}_%03d.jpg" "$i")"
            #file "$f"           # it's useful to test the script
        done < <(ls -Atr --quoting-style=c *.jpg .*.jpg)
    else
        echo -e "\n\033[1;33;41mNothing was done!\033[0m\a"
    fi
    

    You can see a more explained answer here.