Linux shell script to add leading zeros to file names

85,486

Solution 1

Try:

for a in [0-9]*.txt; do
    mv $a `printf %04d.%s ${a%.*} ${a##*.}`
done

Change the filename pattern ([0-9]*.txt) as necessary.


A general-purpose enumerated rename that makes no assumptions about the initial set of filenames:

X=1;
for i in *.txt; do
  mv $i $(printf %04d.%s ${X%.*} ${i##*.})
  let X="$X+1"
done

On the same topic:

Solution 2

Using the rename (prename in some cases) script that is sometimes installed with Perl, you can use Perl expressions to do the renaming. The script skips renaming if there's a name collision.

The command below renames only files that have four or fewer digits followed by a ".txt" extension. It does not rename files that do not strictly conform to that pattern. It does not truncate names that consist of more than four digits.

rename 'unless (/0+[0-9]{4}.txt/) {s/^([0-9]{1,3}\.txt)$/000$1/g;s/0*([0-9]{4}\..*)/$1/}' *

A few examples:

Original    Becomes
1.txt       0001.txt
02.txt      0002.txt
123.txt     0123.txt
00000.txt   00000.txt
1.23.txt    1.23.txt

Other answers given so far will attempt to rename files that don't conform to the pattern, produce errors for filenames that contain non-digit characters, perform renames that produce name collisions, try and fail to rename files that have spaces in their names and possibly other problems.

Solution 3

for a in *.txt; do
  b=$(printf %04d.txt ${a%.txt})
  if [ $a != $b ]; then
    mv $a $b
  fi
done

Solution 4

One-liner:

ls | awk '/^([0-9]+)\.txt$/ { printf("%s %04d.txt\n", $0, $1) }' | xargs -n2 mv

How do I use grep to only match lines that contain \d.txt (IE 1 digit, then a period, then the letters txt)?

grep -E '^[0-9]\.txt$'

Solution 5

Let's assume you have files with datatype .dat in your folder. Just copy this code to a file named run.sh, make it executable by running chmode +x run.sh and then execute using ./run.sh:

#!/bin/bash
num=0
for i in *.dat
do

  a=`printf "%05d" $num`
  mv "$i" "filename_$a.dat"
  let "num = $(($num + 1))"
done

This will convert all files in your folder to filename_00000.dat, filename_00001.dat, etc.

Share:
85,486
David Oneill
Author by

David Oneill

Updated on July 08, 2022

Comments

  • David Oneill
    David Oneill almost 2 years

    I have a folder with about 1,700 files. They are all named like 1.txt or 1497.txt, etc. I would like to rename all the files so that all the filenames are four digits long.

    I.e., 23.txt becomes 0023.txt.

    What is a shell script that will do this? Or a related question: How do I use grep to only match lines that contain \d.txt (i.e., one digit, then a period, then the letters txt)?

    Here's what I have so far:

    for a in [command i need help with]
    do
      mv $a 000$a
    done
    

    Basically, run that three times, with commands there to find one digit, two digits, and three digit filenames (with the number of initial zeros changed).