Jump to content


Batch Rename --Final Question


  • Please log in to reply
8 replies to this topic

#1 Guest_kilbad_*

Guest_kilbad_*
  • Guests

Posted 02 October 2006 - 11:42 AM

I want to use PHP to rename all files in a particular directory with the extension .jpg/.JPG to numbers (with a jpg extension), starting with zero.

For example,

file1.JPG
anotherFILE.jpg
0872.JPG

would be renamed to..

0.jpg
1.jpg
2.jpg


Could someone help me with this script?  I am not sure where to start.

Thanks for the help!
Brendan


#2 obsidian

obsidian
  • Staff Alumni
  • Advanced Member
  • 3,202 posts
  • LocationSeattle, WA

Posted 02 October 2006 - 12:24 PM

you'd probably want to use a simple combination of readdir() and rename()... also, make sure that the file permissions are such that your server will have access to rename the files. something like this should get you pointed in the right direction (i would also recommend padding your names with 0's to help with sorting. i my example, i'm going to create 3 digit names padded with 0:
<?php
$dir = "path/to/directory";
$files = array();
if ($handle = opendir($dir)) {
  while (FALSE !== $file = readdir($handle)) {
    if ($file != '.' && $file != '..') $files[] = $file;
  }
}

for ($i = 0; $i < count($files); $i++) {
  $filename = sprintf("%03d", $i);
  rename("$dir/" . $files[$i], "$dir/" . $filename);
}
?>

another option would be simply to copy() your files with the new name attached and then delete the old filename.

hope this helps.
You can't win, you can't lose, you can't break even... you can't even get out of the game.

<?php
while (count($life->getQuestions()) > 0)
{   $life->study(); } ?>
  LINKS: PHP: Manual MySQL: Manual PostgreSQL: Manual (X)HTML: Validate It! CSS: A List Apart | IE bug fixes | Zen Garden | Validate It! JavaScript: Reference Cards RegEx: Everything RegEx

#3 printf

printf
  • Staff Alumni
  • Advanced Member
  • 889 posts

Posted 02 October 2006 - 12:42 PM

Just another way...

$dir = './some/path/';

$num = 0;

foreach ( glob ( $path . "{*.jpg,*.JPG}", GLOB_BRACE ) AS $file )
{
	rename ( $file, $dir . $num++ . 'jpg' );
}

me!

#4 Guest_kilbad_*

Guest_kilbad_*
  • Guests

Posted 03 October 2006 - 04:19 PM

First, let me thank both of you for your help.  However, I have a follow-up question regarding printf's code..

I don't want to simply use your code without understanding it completely.. so could you, or someone else, explain what is happening with the foreach command (esp. with regard to the GLOB_BRACE).

Just FYI, my modified code::
<?php
$dir = '/mypath/';
$num = 0;
foreach ( glob ( $dir . "{*.jpg,*.JPG}", GLOB_BRACE ) AS $file )
            {rename ( $file, $dir . $num++ . '.jpg' );}
?>



Thank you so much.

Brendan

#5 printf

printf
  • Staff Alumni
  • Advanced Member
  • 889 posts

Posted 03 October 2006 - 04:30 PM

$variable = glob ();

is the same as

opendir ()
readdir ()
loop the directory adding all files to the $variable assigned to it, it return array () of files based on a wildcard (*?) match!
closedir()

GLOB_BRACE

is used to match CASE, because GLOB is case sensitive, so you have to the function glob() to include both upper and lower case naming if you want both included! glob() is also 8X faster than read directory! read directory is better when you don't have a lot of memory to hold the directory listing in a array!


me!

#6 Guest_kilbad_*

Guest_kilbad_*
  • Guests

Posted 04 October 2006 - 04:11 PM

Thank you for that explaination..

I have another follow-up question:: How can I get the list of file names to be renamed numerically in the order they are currently listed, not randomly..?

for example, let's say I have..

IMG_1943.JPG
IMG_1944.JPG
IMG_1945.JPG
IMG_1990.JPG
X.jpg

I want to rename them to..

IMG_1943.JPG --> 0.jpg
IMG_1944.JPG --> 1.jpg
IMG_1945.JPG --> 2.jpg
IMG_1990.JPG --> 3.jpg
X.jpg            --> 4.jpg

Right now when I run the script on a list of files it seems to rename them numerically in a random fashion.

Thanks so much for the help printf.

Brendan





#7 printf

printf
  • Staff Alumni
  • Advanced Member
  • 889 posts

Posted 04 October 2006 - 06:30 PM

Take glob out of the foreach() and then do your foreach renaming after sorting. That's odd, because glob() should sort by default, it does on both Windows and Linux, at least the servers I just tried it on, maybe you need to use | GLOB_NOSORT after GLOB_BRACE to get the right order. Anyway here is another way to do it, using sorting!

<?

// diretory to read 

$dir = './images/';

// file extension

$type = '.jpg';

// starting number

$start = 0;

// run it

$files = glob ( $dir . "{*.jpg,*.JPG}", GLOB_BRACE );

// natrual sort, file names

if  ( ! empty ( $files ) )
{
	natcasesort ( $files );

	foreach ( $files AS $file )
	{
		rename ( $file, $dir . $start++ . $type );
	}
}

?>




me!

#8 Guest_kilbad_*

Guest_kilbad_*
  • Guests

Posted 05 October 2006 - 02:58 PM

Ok, this is my final question regarding this topic...

After the rename of more than 10 files, I get a list that sorts as follows...

0.jpg
1.jpg
10.jpg
11.jpg
12.jpg
2.jpg
3.jpg
4.jpg
5.jpg
6.jpg
7.jpg
8.jpg
9.jpg

However, I would like these files to sort numerically..

My question: Is this a case where padding with zeros is necessary (like obsidian mentioned)?  If so, using printf's example, how do I do that, and how many zeros should I use?

Thanks again so much!  Sorry to have revisited this issue so many times!

Brendan

#9 obsidian

obsidian
  • Staff Alumni
  • Advanced Member
  • 3,202 posts
  • LocationSeattle, WA

Posted 05 October 2006 - 03:08 PM

yes, padding with zeros would be necessary. basically, just decide what the MOST digits you will need is, and do this when you rename it:
<?php
// simply replace this line:
rename ( $file, $dir . $start++ . $type );

// with this:
rename ( $file, $dir . sprintf("%03d", $start++) . $type );
?>

that code will make it padded to 3 digits. simply change the '3' in the sprintf() above to any number of digits you're after. good luck!
You can't win, you can't lose, you can't break even... you can't even get out of the game.

<?php
while (count($life->getQuestions()) > 0)
{   $life->study(); } ?>
  LINKS: PHP: Manual MySQL: Manual PostgreSQL: Manual (X)HTML: Validate It! CSS: A List Apart | IE bug fixes | Zen Garden | Validate It! JavaScript: Reference Cards RegEx: Everything RegEx




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users