skip to Main Content

I have thousands of files in different folders that I would like to rename with their directories and, but less importantly, edit a few details after.

As a structure example:

FOLDER A

---> folder 1

- 1.jpg
- 2.jpg

---> folder 2

- 1.jpg
- 2.jpg

FOLDER B

---> folder 1

- 1.jpg
- 2.jpg

...

The end name should be: FOLDER A_folder 1_1.jpg …etc

and the less important edit: FOLDER A - 1_1.jpg …etc

I don’t know if it’s relevant, but I have Ubuntu and from the terminal I’ve test tried this:

for file in Folders*/*/*/*.jpg; do
  mv "$file" "${file////_}";
done

It correctly renames the files with their paths but simultaneously extracts them and put them in the main folder, how do I avoid that?

2

Answers


  1. This should do the trick:

    SAVEIFS=$IFS
    IFS=$(echo -en "nb")
    for f1 in `ls`; 
        do for f2 in `ls "$f1"`; 
            do for f3 in `ls $f1/$f2`; 
                do mv "$f1/$f2/$f3" "$f1/$f2/${f1}_${f2}_$f3"; 
            done; 
        done; 
    done
    IFS=$SAVEIFS
    
    Login or Signup to reply.
  2. You need to add the path to the "target" file (the second parameter of the mv command) since you replaced all / with _ practically removing the path and making it part of the new name:

    for file in FOLDER*/*/*; do
        mv "$file" "$(dirname "$file")/${file////_}";
    done
    

    TEST

    Directories and files before running the loop:

    $ find .
    .
    ./FOLDER B
    ./FOLDER B/folder 2
    ./FOLDER B/folder 2/2.jpg
    ./FOLDER B/folder 2/1.jpg
    ./FOLDER B/folder 1
    ./FOLDER B/folder 1/2.jpg
    ./FOLDER B/folder 1/1.jpg
    ./FOLDER A
    ./FOLDER A/folder 2
    ./FOLDER A/folder 2/2.jpg
    ./FOLDER A/folder 2/1.jpg
    ./FOLDER A/folder 1
    ./FOLDER A/folder 1/2.jpg
    ./FOLDER A/folder 1/1.jpg
    $
    

    Renaming the files and the results:

    $ for file in FOLDER*/*/*; do
    >     mv "$file" "$(dirname "$file")/${file////_}";
    > done
    $ find .
    .
    ./FOLDER B
    ./FOLDER B/folder 2
    ./FOLDER B/folder 2/FOLDER B_folder 2_1.jpg
    ./FOLDER B/folder 2/FOLDER B_folder 2_2.jpg
    ./FOLDER B/folder 1
    ./FOLDER B/folder 1/FOLDER B_folder 1_1.jpg
    ./FOLDER B/folder 1/FOLDER B_folder 1_2.jpg
    ./FOLDER A
    ./FOLDER A/folder 2
    ./FOLDER A/folder 2/FOLDER A_folder 2_1.jpg
    ./FOLDER A/folder 2/FOLDER A_folder 2_2.jpg
    ./FOLDER A/folder 1
    ./FOLDER A/folder 1/FOLDER A_folder 1_1.jpg
    ./FOLDER A/folder 1/FOLDER A_folder 1_2.jpg
    $
    

    As for your "less important edit," you can rename the files again, like this:

    for file in FOLDER*/*/*; do
        mv "$file" "${file//_folder/ -}";
    done
    

    Note that you don’t need to add the path here since the _folder to - substitution done to the file variable only affects the file name and not the path.

    Final result:

    $ find .
    .
    ./FOLDER B
    ./FOLDER B/folder 2
    ./FOLDER B/folder 2/FOLDER B - 2_1.jpg
    ./FOLDER B/folder 2/FOLDER B - 2_2.jpg
    ./FOLDER B/folder 1
    ./FOLDER B/folder 1/FOLDER B - 1_1.jpg
    ./FOLDER B/folder 1/FOLDER B - 1_2.jpg
    ./FOLDER A
    ./FOLDER A/folder 2
    ./FOLDER A/folder 2/FOLDER A - 2_1.jpg
    ./FOLDER A/folder 2/FOLDER A - 2_2.jpg
    ./FOLDER A/folder 1
    ./FOLDER A/folder 1/FOLDER A - 1_1.jpg
    ./FOLDER A/folder 1/FOLDER A - 1_2.jpg
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search