How to rename multiple files starting from 1 to unlimited ( to finish all files ) ?
My files looks like:
file.jpeg.jpg
fileA.jpeg.jpg
fileB.jpeg.jpg
Output:
1.jpeg.jpg
2.jpeg.jpg
3.jpeg.jpg
I'm using Cygwin so I can't install packages
How to rename multiple files starting from 1 to unlimited ( to finish all files ) ?
My files looks like:
file.jpeg.jpg
fileA.jpeg.jpg
fileB.jpeg.jpg
Output:
1.jpeg.jpg
2.jpeg.jpg
3.jpeg.jpg
I'm using Cygwin so I can't install packages
Try:
n=0; for f in *.jpg; do mv "$f" "$((++n)).jpeg.jpg"; done
Or, the same thing spread out over multiple lines:
n=0
for f in *.jpg
do
mv "$f" "$((++n)).jpeg.jpg"
done
n=0
This initializes the variable n
n.
for f in *.jpg; do
This starts a loop over all files in the current directory whose names end with .jpg
.
mv "$f" "$((++n)).jpeg.jpg"
This renames the files as you want. In bash, $((...))
does arithmetic. Here, we have it increment n
each time it is run.
done
This signals the end of the loop.
This code will work even if there are files whose names contain spaces, tabs, newlines, or other difficult characters.
The glob test*.in
is expanded into a list of files in alphabetical order. This is documented in man bash
:
bash scans each word for the characters *, ?, and [. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern (see Pattern Matching below). [Emphasis added.]
Note that the meaning of alphabetical sorting may depend on your locale setting.
j=0;
for i in `ls`
do
mv $i $j.jpeg.jpg
j=`echo $j + 1 | bc`
done
Since the number of files can be "unlimited", there is a builtin limit to the size of the command line. See https://stackoverflow.com/questions/19354870/bash-command-line-and-input-limit . Therefore, I would use find
to solve this. E.g, in bash:
cd /path/to/directory
n=1
find . -maxdepth 1 -type f -name "*.jpeg.jpg" | sort | while read file; do
mv "$file" $n.jpeg.jpg
let n=n+1
done
The steps are as follows, line-by-line:
find
in the .
(current) directory, and do not burrow into any subdirectories (-maxdepth 1
), and look at only regular files -type f
, and return only files whose name matches the pattern *.jpeg.jpg
, and print their names (by default). Pipe the output of the find command to the sort command so they are in order (sort can handle very large stdin). Pipe the output of sort to a while
/read
loop, which will set each line of input to the variable file
, line by line.file
variable to a file named by the $n
variable, concantenated with the string `.jpeg.jpg'You can handle a very large directory this way. It's fairly immune to 'weird' (aka "characters not in the printable ASCII set") file names. It can be made even more immune but that's probably unnecessary for this case, I'm guessing (It involves using the -print0
option, and probably the xargs
command).
This version will keep the new files in the same order when you list them aphabetically (as in the output of ls
):
#!/bin/sh
i=0
for f in *.jpeg.jpg
do
mv "$f" "$(printf '%011d.jpeg.jpg' $i)"
i=$(expr $i + 1)
done