How can I add numbers to the files in one directory?
In one directory I have files like below:
fileA
fileB
fileC
fileD
I want to prepend ascending numbers to them, like this:
1_fileA
2_fileB
3_fileC
4_fileD
Thank you in advance.
How can I add numbers to the files in one directory?
In one directory I have files like below:
fileA
fileB
fileC
fileD
I want to prepend ascending numbers to them, like this:
1_fileA
2_fileB
3_fileC
4_fileD
Thank you in advance.
One of the solutions:
cd <your dir> then run in bash (copy and paste in command-line):
n=1; for f in *; do mv "$f" "$((n++))_$f"; done
Bash script case:
#!/bin/bash
n=1
for f in *
do
if [ "$f" = "rename.sh" ]
then
continue
fi
mv "$f" "$((n++))_$f"
done
save it as rename.sh to dir with files to rename, chmod +x rename.sh then run it ./rename.sh
Open your directory in Nautilus.
Highlight all of the files.
Right-click, and select "Rename..." from the context menu.
On the Rename dialog, click the +Add button.
Select "1,2,3,4" under "Automatic Numbers"
Then, in the Rename dialog, in the text entry field, insert an underscore "_" character between "[1, 2, 3]" and "[Original file name]".
It should look like "[1, 2, 3]_[Original file name]"
Click the Rename button.
If there are more than 9 files, I would use printf to pad the number to get the expected sort order, like this
n=0
for f in *
do printf -v new "%2d$((++n))_$f"
echo mv -v -- "$f" "$new"
done
Remove echo when you see the correct result.
In this line, do printf -v new "%2d$((++n))_$f" we create a format for the new filenames and put it into the variable new.
%2d is a 2 digit decimal number. Instead of 2d, you can use 3d etc to get another leading 0 (if you have more than 99 files).
((++n)) increments the variable n (which we set to 0 at the start of the script). Since it is iterated once each time the loop is run, files get incremented name prefixes.
-v makes mv print what will be changed.
-- in the mv statement is to prevent filenames that start with - being interpreted as options.
That’s a job for file-rename
(aka perl rename or just rename):
file-rename -n 'our $i; if (!$i) {$i++}; s/^/sprintf("%d_", $i++)/e' *
This defines a variable, increases it if it’s not set (else it would start with 0 instead of 1) and replaces the beginning of the filename with the number increasing it every time. You can change the format easily, e.g. to make it three-digit (001, 002, …) use "%03d_". Running it with -n only prints the changes, to actually perform the renaming remove this flag.
Using the alternatives system, rename is linked to file-rename on my system.
$ ls -1
fileA
fileB
fileC
fileD
$ rename -n 'our $i; if (!$i) {$i++}; s/^/sprintf("%d_", $i++)/e' *
rename(fileA, 1_fileA)
rename(fileB, 2_fileB)
rename(fileC, 3_fileC)
rename(fileD, 4_fileD)
$ rename 'our $i; if (!$i) {$i++}; s/^/sprintf("%d_", $i++)/e' *
$ ls -1
1_fileA
2_fileB
3_fileC
4_fileD
One option is
cd /path/to/folder/
ls -1v | rename -n -v 's/^/sprintf("%02d_", ++our$i)/e'
This works fine, except with the file names with new line "\n". Switch '-1v'takes care of spaces and tabs,
Other commands posted here change the order of files with numbers e.g. 10a comes before 1a.
Whichever suits in a situation.
I had some time to test all these commands. Here are the results.
$ ls
001abc.txt '10a bc.txt' 1abc.txt '2ab c.txt' 'a'$'\t''bc.txt'
$ ls -1v | rename -n -v 's/^/sprintf("%02d_", ++our$i)/e'
Reading filenames from file handle (GLOB(0x55cb57991b28))
rename(001abc.txt, 01_001abc.txt)
rename(1abc.txt, 02_1abc.txt)
rename(2ab c.txt, 03_2ab c.txt)
rename(10a bc.txt, 04_10a bc.txt)
rename(a bc.txt, 05_a bc.txt)
$ n=1; for f in *; do echo mv "$f" "$((n++))_$f"; done
mv 001abc.txt 1_001abc.txt
mv 10a bc.txt 2_10a bc.txt
mv 1abc.txt 3_1abc.txt
mv 2ab c.txt 4_2ab c.txt
mv a bc.txt 5_a bc.txt
$ for f in *; do printf -v new "%2d$((++n))_$f"; echo mv -v -- "$f" "$new"; done
mv -v -- 001abc.txt 09_001abc.txt
mv -v -- 10a bc.txt 010_10a bc.txt
mv -v -- 1abc.txt 011_1abc.txt
mv -v -- 2ab c.txt 012_2ab c.txt
mv -v -- a bc.txt 013_a bc.txt
$ ./rename.sh
mv 001abc.txt 1_001abc.txt
mv 10a bc.txt 2_10a bc.txt
mv 1abc.txt 3_1abc.txt
mv 2ab c.txt 4_2ab c.txt
mv a bc.txt 5_a bc.txt
$ rename -n 'our $i; if (!$i) {$i++}; s/^/sprintf("%d_", $i++)/e' *
rename(001abc.txt, 1_001abc.txt)
rename(10a bc.txt, 2_10a bc.txt)
rename(1abc.txt, 3_1abc.txt)
rename(2ab c.txt, 4_2ab c.txt)
rename(a bc.txt, 5_a bc.txt)
rename(rename.sh, 6_rename.sh)
$ for f in *; do printf -v new "%2d$((++n))_$f"; echo mv -v -- "$f" "$new"; done
mv -v -- 001abc.txt 01_001abc.txt
mv -v -- 10a bc.txt 02_10a bc.txt
mv -v -- 1abc.txt 03_1abc.txt
mv -v -- 2ab c.txt 04_2ab c.txt
mv -v -- a bc.txt 05_a bc.txt
mv -v -- rename.sh 06_rename.sh
An additional way with Python's rename tool (replace the print with os.rename to actually perform the task if the results look correct)
$ cd "/your/file/path" && python -c "\
import os; \
[print('{0}_{1}'.format(i, f)) \\
for i, f in enumerate(filter(lambda x: not os.path.isdir(x), os.listdir('.')), 1)]"
1_fileA
2_fileB
3_fileC
4_fileD
...
26_fileZ
to rename, replace the print line with
[os.rename(f, '{0}_{1}'.format(i, f)) \
It first looks through a list of the files in the location result from the cd command. os.listdir('.')
Removes any directories from the that list filter(lambda x: not os.path.isdir(x), os.listdir('.'))
Then the resulting filenames are traversed, along with a counter to append to the new name for i, f in enumerate(..., 1). Here f is the file's name and i is the counter. The counter is set to start at 1 instead of 0.
In the format string, '{0}_{1}'.format(i, f), {0} is the first given variable, the counter, and {1} is the file's name separated with the '_' character.
Some padding can be given to the numbers like in some of the other answers.
$ cd "/your/file/path" && python -c "\
import os; \
pad = len(str(len(os.listdir('.')))); \
[print('{0:0{2}d}_{1}'.format(i, f, pad)) \\
for i, f in enumerate(filter(lambda x: not os.path.isdir(x), os.listdir('.')), 1)]"
01_fileA
02_fileB
...
26_fileZ
to rename, replace the print line with
[os.rename(f, '{0:0{2}d}_{1}'.format(i, f, pad)) \
{2} is the third given variable, in this case the padding which is set to the the length (number of digits) of the number of files in the directory. If there are 23 files, pad = 2. If there are 101 files, pad = 3. 45678, padding = 5, etc.