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?
CodePudding user response:
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
CodePudding user response:
This should do the trick:
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
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