Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Batch rename sequential files by padding with zeroes

I have a bunch of files named like so:

output_1.png output_2.png ... output_10.png ... output_120.png 

What is the easiest way of renaming those to match a convention, e.g. with maximum four decimals, so that the files are named:

output_0001.png output_0002.png ... output_0010.png output_0120.png 

This should be easy in Unix/Linux/BSD, although I also have access to Windows. Any language is fine, but I'm interested in some really neat one-liners (if there are any?).

like image 604
slhck Avatar asked Mar 24 '11 10:03

slhck


People also ask

How do I batch rename files sequentially?

You can press and hold the Ctrl key and then click each file to rename. Or you can choose the first file, press and hold the Shift key, and then click the last file to select a group.

How do I rename multiple files with sequential numbers in Windows 11?

You can also select to rename multiple files by pressing an additional keyboard key. Press and hold the Ctrl key to choose files to rename. Entering a new title for one file in a folder will then rename all the others selected with the same name (with a numerical modifier at the end).

How do I rename multiple files without parentheses?

In the File Explorer window, select all files, right-click and select rename. Windows will select the starting number as the number supplied between the round brackets so name the file using a number that is 1 digit more than the number of digits required.


2 Answers

Python

import os path = '/path/to/files/' for filename in os.listdir(path):     prefix, num = filename[:-4].split('_')     num = num.zfill(4)     new_filename = prefix + "_" + num + ".png"     os.rename(os.path.join(path, filename), os.path.join(path, new_filename)) 

you could compile a list of valid filenames assuming that all files that start with "output_" and end with ".png" are valid files:

l = [(x, "output" + x[7:-4].zfill(4) + ".png") for x in os.listdir(path) if x.startswith("output_") and x.endswith(".png")]  for oldname, newname in l:     os.rename(os.path.join(path,oldname), os.path.join(path,newname)) 

Bash

(from: http://www.walkingrandomly.com/?p=2850)

In other words I replace file1.png with file001.png and file20.png with file020.png and so on. Here’s how to do that in bash

#!/bin/bash num=`expr match "$1" '[^0-9]*\([0-9]\+\).*'` paddednum=`printf "%03d" $num` echo ${1/$num/$paddednum} 

Save the above to a file called zeropad.sh and then do the following command to make it executable

chmod +x ./zeropad.sh 

You can then use the zeropad.sh script as follows

./zeropad.sh frame1.png 

which will return the result

frame001.png 

All that remains is to use this script to rename all of the .png files in the current directory such that they are zeropadded.

for i in *.png;do mv $i `./zeropad.sh $i`; done 

Perl

(from: Zero pad rename e.g. Image (2).jpg -> Image (002).jpg)

use strict; use warnings; use File::Find;  sub pad_left {    my $num = shift;     if ($num < 10) {       $num = "00$num";    }    elsif ($num < 100) {       $num = "0$num";    }     return $num; }  sub new_name {    if (/\.jpg$/) {       my $name = $File::Find::name;       my $new_name;       ($new_name = $name) =~ s/^(.+\/[\w ]+\()(\d+)\)/$1 . &pad_left($2) .')'/e;       rename($name, $new_name);       print "$name --> $new_name\n";    } }  chomp(my $localdir = `pwd`);# invoke the script in the parent-directory of the                             # image-containing sub-directories  find(\&new_name, $localdir); 

Rename

Also from above answer:

rename 's/\d+/sprintf("%04d",$&)/e' *.png 
like image 159
dting Avatar answered Sep 24 '22 01:09

dting


Fairly easy, although it combines a few features not immediately obvious:

@echo off setlocal enableextensions enabledelayedexpansion rem iterate over all PNG files: for %%f in (*.png) do (     rem store file name without extension     set FileName=%%~nf     rem strip the "output_"     set FileName=!FileName:output_=!     rem Add leading zeroes:     set FileName=000!FileName!     rem Trim to only four digits, from the end     set FileName=!FileName:~-4!     rem Add "output_" and extension again     set FileName=output_!FileName!%%~xf     rem Rename the file     rename "%%f" "!FileName!" ) 

Edit: Misread that you're not after a batch file but any solution in any language. Sorry for that. To make up for it, a PowerShell one-liner:

gci *.png|%{rni $_ ('output_{0:0000}.png' -f +($_.basename-split'_')[1])} 

Stick a ?{$_.basename-match'_\d+'} in there if you have other files that do not follow that pattern.

like image 30
Joey Avatar answered Sep 22 '22 01:09

Joey