Linux shell script to add leading zeros to file names

Viewed 87253

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).

10 Answers

To provide a solution that's cautiously written to be correct even in the presence of filenames with spaces:

#!/usr/bin/env bash

pattern='%04d'  # pad with four digits: change this to taste

# enable extglob syntax: +([[:digit:]]) means "one or more digits"
# enable the nullglob flag: If no matches exist, a glob returns nothing (not itself).
shopt -s extglob nullglob

for f in [[:digit:]]*; do               # iterate over filenames that start with digits
  suffix=${f##+([[:digit:]])}           # find the suffix (everything after the last digit)
  number=${f%"$suffix"}                 # find the number (everything before the suffix)
  printf -v new "$pattern" "$number" "$suffix"  # pad the number, then append the suffix
  if [[ $f != "$new" ]]; then                   # if the result differs from the old name
    mv -- "$f" "$new"                           # ...then rename the file.
  fi
done

There is a rename.ul command installed from util-linux package (at least in Ubuntu) by default installed.

It's use is (do a man rename.ul):

rename [options] expression replacement file...

The command will replace the first occurrence of expression with the given replacement for the provided files.

While forming the command you can use:

rename.ul -nv replace-me with-this in-all?-these-files*

for not doing any changes but reading what changes that command would make. When sure just reexecute the command without the -v (verbose) and -n (no-act) options

for your case the commands are:

rename.ul "" 000 ?.txt
rename.ul "" 00 ??.txt
rename.ul "" 0 ???.txt
Related