How can I prepend filenames with ascending numbers like 1_ 2_?

5,736

Solution 1

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

Solution 2

  1. Open your directory in Nautilus.

  2. Highlight all of the files.

  3. Right-click, and select "Rename..." from the context menu.

  4. On the Rename dialog, click the +Add button.

  5. Select "1,2,3,4" under "Automatic Numbers"

  6. 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]"

  7. Click the Rename button.

Select "1,2,3,4" in the Rename dialog

The renamed files

Solution 3

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.

Explanation

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.

Solution 4

That’s a job for file-rename Install 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.

Example run

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

Solution 5

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
Share:
5,736

Related videos on Youtube

paweljvn
Author by

paweljvn

I speak English and Polish (native). I also have strong basics in German and Spanish. I am a bachelor of taxes. I also have two more years to graduate at law. In 3 years I will obtain engineer's degree in Computer Science (software development specialization). I used to create websites with HTML3 but they said it's not programming. So I started learning back-end languages (Python, Java). I also have other hobbies as kitesurfing or specialty coffee brewing. I find this website very helpful in clarifying many complicated issues that every hungry programmer meets.

Updated on September 18, 2022

Comments

  • paweljvn
    paweljvn almost 2 years

    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.

    • paweljvn
      paweljvn over 5 years
      @PerlDuck Yes, I have to enumarte them changing their name.
    • Justin
      Justin over 5 years
  • paweljvn
    paweljvn over 5 years
    but can I also run this from vim? I mean to put your code in vim as #!/bin/bash and the run it from the command line?
  • mature
    mature over 5 years
    Sure. But you need add this simple command to bash file. Then You need to solve self-renaming of this rename.sh file.
  • mature
    mature over 5 years
    Added example with bash file. If you need something like bash command to run it in any file system place, you need use first example saved in bash file and add this bash file to PATH with alias.
  • myrdd
    myrdd over 5 years
    err, you still use rename in ”Example run“ ... ;)
  • Marzl
    Marzl over 2 years
    being able to handle filenames with whitespace ie. newlines, tabs and spaces is a big ++