You are not logged in.
I have a folder with many subfolders with many files. I want to rename all files to sequential numbers (0001.jpg, 0002.jpg, .0003,jpg ...) but i want to save the path. I mean that the files should not be saved in the root directory (where i launched the script), but I want them to remain in original subdirectorys. How can i do this?
Last edited by cypherinside (2011-11-14 18:37:16)
To be or not to be? ...Not to be! (Last Action Hero)
Offline
What script are you using? Or are you trying to write one?
Last edited by karol (2011-11-13 15:03:28)
Offline
Offline
@Karol: I'm trying to write one
@Falconindi: It doesn't works
I tried this
i=0
find -type f -iname "*.jpg" | while read x; do
mv "${x}" "$(printf "%04d" ${i}).jpg"
i=$((i+1))
doneand it works but all the file are moved to the root directory! I want to preserve their path.
Last edited by cypherinside (2011-11-13 19:25:49)
To be or not to be? ...Not to be! (Last Action Hero)
Offline
... for src in "$1"/*; do printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))" mv "$src" "$dest" ...
Question: I have done most of my coding in C and C++, I hack in Python. I have learned the hard way avoid structures like that. What is happening under-the-hood that makes it safe to modify the collection through which you are iterating?
Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
The shortest way to ruin a country is to give power to demagogues.— Dionysius of Halicarnassus
---
How to Ask Questions the Smart Way
Offline
This worked on a test directory with a single subdirectory. You must give it the parent directory name. I haven't tested it thoroughly.
#!/bin/bash
# requires a parent directory name
find "$1" -depth -iname "*.jpg" | while read file ; do
directory=$(dirname "$file")
oldfilename=$(basename "$file")
newfilename=$(printf "%04d" ${i}).jpg
i=$((i+1))
mv "$directory/$oldfilename" "$directory/$newfilename"
done
exit 0Offline
falconindy wrote:... for src in "$1"/*; do printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))" mv "$src" "$dest" ...Question: I have done most of my coding in C and C++, I hack in Python. I have learned the hard way avoid structures like that. What is happening under-the-hood that makes it safe to modify the collection through which you are iterating?
"$1"/* isn't a collection persay. It expands to the list of matches for the glob. You're essentially making a copy of a list and then writing a new list, based on the old names.
Anyways, yeah I missed the part with about subdirectories. find works, but I'd prefer to do this still in bash:
#!/bin/bash
walk() {
for src in "$1"/*; do
if [[ -d $src ]]; then
walk "$src"
continue
fi
printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"
mv "$src" "$dest"
done
}
[[ $1 ]] || exit 1
walk "$1"Offline
@thisoldman: it doesn't works (the numeration is caotic)
@falconindy: thanks it works, but i want the numbering starts with 0001 for each folder.
I did not know you could define functions in bash scripts... this is wonderful.
I understand something (but not too much) about C. Can you explain me the script?
walk() {You have defined a function
for src in "$1"/*; do ## "$1"/*are all the subdirectory. Can i use "$(pwd)/*" instead of "$1/*"? In this way i don't write the parent directory
if [[ -d $src ]];
walk "$src"
continue
fiI dont' understand
printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"Stores in dest... what? I assume that %s is a string as in C language, infact you give "$1" as argument (but why?). And I assume that "$((++i))" is like i=$((i+1)). Is it right?
mv "$src" "$dest"
done
}Ok
[[ $1 ]] || exit 1I don't understand.
walk "$1"Ok
To be or not to be? ...Not to be! (Last Action Hero)
Offline
for src in "$1"/*; do ## "$1"/*are all the subdirectory. Can i use "$(pwd)/*" instead of "$1/*"? In this way i don't write the parent directory
If you want to specify $PWD, just call the script with an argument of '.' to point it at PWD.
if [[ -d $src ]]; walk "$src" continue fiI dont' understand
It's simple recursion. You don't want to rename directories, you want to process the contents of the directory in the same way you're processing the current directory.
printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"Stores in dest... what? I assume that %s is a string as in C language, infact you give "$1" as argument (but why?). And I assume that "$((++i))" is like i=$((i+1)). Is it right?
It's the bash equivalent of sprintf(3).
[[ $1 ]] || exit 1I don't understand.
If $1 doesn't exist (i.e. you passed no arguments to the script), then refuse to run and exit immediately with an error.
You weren't really clear in your requirements, so I wrote it as I interpreted it. If you want to reset the numbering for each directory, scope 'i' locally:
#!/bin/bash
walk() {
local -i i=0
for src in "$1"/*; do
if [[ -d $src ]]; then
walk "$src"
continue
fi
printf -v dest '%s/%04d.jpg' "$1" "$(( ++i ))"
mv "$src" "$dest"
done
}
[[ $1 ]] || exit 1
walk "$1"Offline
Yes, I'm sorry if I was not very clear in my question (as you may have noticed I did not express very well in English... Google translate helps me!
)
If you want to specify $PWD, just call the script with an argument of '.' to point it at PWD.
No, really I want call the script without arguments (if this is possible), because this script will be part of a bigger script that doesn't use arguments (so I must run it inside the parent directory).
To be or not to be? ...Not to be! (Last Action Hero)
Offline
Offline
I'm sorry if I insist but I do not want to use the script without understanding it: what's the benefit to use "$1"? Can i directly use $(pwd)?
EDIT: with walk "${1:$PWD}" it don't work. The script is executed in / directory!!! Luckily I used immediately CTRL+C... (fiuuuuu!) otherwise my home directory would be irretrievably compromised
Last edited by cypherinside (2011-11-13 23:12:03)
To be or not to be? ...Not to be! (Last Action Hero)
Offline
The point of the change I just mentioned is that if you do not supply an argument, the script will default to $PWD.
Yes, you can hardcode in $PWD, but I fail to see the point of doing so.
Offline
read the edit, please ![]()
Last edited by cypherinside (2011-11-13 23:18:25)
To be or not to be? ...Not to be! (Last Action Hero)
Offline
Thanks for everything.
To be or not to be? ...Not to be! (Last Action Hero)
Offline