Renaming a set of files to 001, 002,
Solution 1
If I understand right, you have e.g. image_001.jpg, image_003.jpg, image_005.jpg, and you want to rename to image_001.jpg, image_002.jpg, image_003.jpg.
EDIT: This is modified to put the temp file in the current directory. As Stephan202 noted, this can make a significant difference if temp is on a different filesystem. To avoid hitting the temp file in the loop, it now goes through image*
i=1; temp=$(mktemp -p .); for file in image*
do
mv "$file" $temp;
mv $temp $(printf "image_%0.3d.jpg" $i)
i=$((i + 1))
done
Solution 2
A simple loop (test with echo
, execute with mv
):
I=1
for F in *; do
echo "$F" `printf image_%03d.jpg $I`
#mv "$F" `printf image_%03d.jpg $I` 2>/dev/null || true
I=$((I + 1))
done
(I added 2>/dev/null || true
to suppress warnings about identical source and target files. If this is not to your liking, go with Matthew Flaschen's answer.)
Solution 3
Some good answers here already; but some rely on hiding errors which is not a good idea (that assumes mv
will only error because of a condition that is expected - what about all the other reaons mv
might error?).
Moreover, it can be done a little shorter and should be better quoted:
for file in *; do
printf -vsequenceImage 'image_%03d.jpg' "$((++i))"
[[ -e $sequenceImage ]] || \
mv "$file" "$sequenceImage"
done
Also note that you shouldn't capitalize your variables in bash scripts.
Solution 4
Try the following script:
This code snipped should do the job:
./numerate.sh -d <your image folder> -b <start number> -L 3 -p image_ -s .jpg -o numerically -r
Solution 5
This does the reverse of what you are asking (taking files of the form *.jpg.001 and converting them to *.001.jpg), but can easily be modified for your purpose:
for file in *
do
if [[ "$file" =~ "(.*)\.([[:alpha:]]+)\.([[:digit:]]{3,})$" ]]
then
mv "${BASH_REMATCH[0]}" "${BASH_REMATCH[1]}.${BASH_REMATCH[3]}.${BASH_REMATCH[2]}"
fi
done
DisgruntledGoat
I'm a web developer and programmer from the UK. I'll fill this out more when I can be bothered; really I'm just trying to get the autobiography badge.
Updated on July 31, 2022Comments
-
DisgruntledGoat almost 2 years
I originally had a set of images of the form image_001.jpg, image_002.jpg, ...
I went through them and removed several. Now I'd like to rename the leftover files back to image_001.jpg, image_002.jpg, ...
Is there a Linux command that will do this neatly? I'm familiar with rename but can't see anything to order file names like this. I'm thinking that since
ls *.jpg
lists the files in order (with gaps), the solution would be to pass the output of that into a bash loop or something? -
Matthew Flaschen almost 15 yearsThis doesn't work. Most of the images will still have their original names, so the mv will fail.
-
Stephan202 almost 15 years@Matthew: good spot. Now changed the code so that all files are moved to a temporary directory.
-
Stephan202 almost 15 yearsNice (as long as mktemp creates a file on the same volume, otherwise moving to a temporary subdirectory is faster)
-
Matthew Flaschen almost 15 yearsTo be clear, it will work on the other images, but will produce spurious errors that can break e.g. Makefiles.
-
Stephan202 almost 15 years@Matthew: on second thought, failing is not a problem. I'll revert the code.
-
Matthew Flaschen almost 15 yearsKeep in mind, mv fails even with the /dev/null, so make (and similar) still break.
-
Stephan202 almost 15 yearsDoh. I should go to bed. Anyway, should be fixed now.
-
Dimitre Radoulov almost 15 yearsWith recent versions of bash you can use: printf -vsequenceImage 'image_%03d.jpg' $((++i))
-
Dimitre Radoulov almost 15 yearsActually, you're manipulating the i variable in a subshell, so in your example it does not get incremented.
-
lhunath almost 15 yearsradoulov: well spotted, thanks. I recon I should test what I write.
-
DisgruntledGoat almost 15 yearsI'm going to mark this as the answer, but I didn't need to use a temp directory: my images actually started at 002 (with gaps), therefore there couldn't be any conflicts. 002 is renamed 001, 005->002, 006->003 and so on.
-
DisgruntledGoat almost 15 yearsFor other people's reference, my final command was: i=0; for file in *.jpg; do mv "$file" $(printf "image_%0.3d.jpg" $i); i=$((i+1)); done