Bulk renaming using regex in Php - php

I have a folder in a server with a lot of images and I would like to rename some images. Images that contain (1 example:
112345(1.jpg to 112345.jpg. How can I do this using regex in PHP? I have to mention that my knowledge of PHP is very limited and it's the only language that can effectively do the scripting.

preg_match('/\(1/', $entry) will help you.
Also, you need to pay attention to "what if the file has a duplicate after the rename".
$directory = "/path/to/images";
if ($handle = opendir($directory)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != '.' && $entry != '..') {
// Check "(1"
if (preg_match('/\(1/', $entry)) {
// Rename file
$old = $directory . '/' . $entry;
$new = str_replace('(1', '', $old);
// Check duplicate
if (file_exists($new)) {
$extension = strrpos($new, '.');
$new = substr($new, 0, $extension) . rand() . substr($new, $extension); // Basic rand()
}
rename($old, $new);
}
}
}
closedir($handle);
}

If you want only remove some substring from images names you can do this without regex. Use str_replace function to replace substring to empty string.
As example:
$name = "112345(1.jpg";
$substring = "(1";
$result = str_replace($substring, "", $name);

You can use scandir and preg_grep to filter out the files that needs to be renamed.
$allfiles = scandir("folder"); // replace with folder with jpg files
$filesToRename = preg_grep("/\(1\.jpg/i", $allfiles);
Foreach($filesToRename as $file){
Echo $file . " " . Var_export(rename($file, str_replace("(1.", ".", $file));
}
This is untested code and in theory it should echo the filename and true/false if the rename worked or not.

Only use regex for this if you need to assert the position of the substring, e.g. if you have filenames like Copy (1)(1.23(1.jpg a simple string replacement will go wrong.
$re = '/^(.+)\(1(\.[^\\\\]+)$/';
$subst = '$1$2';
$directory = '/my/root/folder';
if ($handle = opendir($directory )) {
while (false !== ($fileName = readdir($handle))) {
$newName = preg_replace($re, $subst, $fileName);
rename($directory . $fileName, $directory . $newName);
}
closedir($handle);
}
The regular expression used searches for the part before and after the file extension, put the pieces into capturing groups, and glue them together again in the preg_replace without the (1.

Related

Unexpected output for filename

<?php
error_reporting(E_ALL);
ini_set('display_errors' ,1);
//expression to be found in file name
$find = '.5010.';
//directory name
//we will store renamed files here
$dirname = '5010';
if(!is_dir($dirname))
mkdir($dirname, 0777);
//read all files from a directory
//skip directories
$directory_with_files = './';
$dh = opendir($directory_with_files);
$files = array();
while (false !== ($filename = readdir($dh)))
{
if(in_array($filename, array('.', '..')) || is_dir($filename))
continue;
$files[] = $filename;
}
//iterate collected files
foreach($files as $file)
{
//check if file name is matching $find
if(stripos($file, $find) !== false)
{
//open file
$handle = fopen($file, "r");
if ($handle)
{
//read file, line by line
while (($line = fgets($handle)) !== false)
{
//find REF line
$refid = 'REF*2U*';
if(stripos($line, $refid) !== false)
{
//glue refernce numbers
//check if reference number is not empty
$refnumber = str_replace(array($refid, '~'), array('', ''), $line);
if($refnumber != '')
{
$refnumber = '_'. $refnumber .'_';
$filerenamed = str_replace($find, $refnumber, $file);
copy($file, $dirname . '/' . $filerenamed);
}
echo $refnumber . "\n";
}
}
//close file
fclose($handle);
}
}
}
?>
I have this code, the output should be the replacement of ".5010." with "ref" in the final name, however, when I run the code, it just shows me up to ref not the rest of the file name, I tried it on my computer putty and turns out there's a "?" after the ref number, is there any way I could fix this?
For example; My file is 4867586.5010.476564.ed
After the code executes and reads the file, the output should be: 4867586_SMIL01_476564.ed but instead its: 4867586_SMIL01
And when I checked it out on putty the file name was: 4867586_SMIL01?_476564.ed
The ? in the filename denotes that there's a a non-printable character somewhere in the refnumber line.
This is most likely a line-ending character, or something else.
If it's the former, then that can be solved by changing the line:
$refnumber = str_replace(array($refid, '~'), array('', ''), $line);
to
$refnumber = str_replace(array($refid, '~'), array('', ''), $line);
$refnumber = trim($refnumber); // remove any whitespaces or line endings.
If it's the latter, then you'll need to sanitize your $refnumber variable using one of the file sanitizer functions available online.

Remove string from filename for all files (image files) available in the directory without affecting its extensions

Need to remove user requested string from file name. This below is my function.
$directory = $_SERVER['DOCUMENT_ROOT'].'/path/to/files/';
$strString = $objArray['frmName']; // Name to remove which comes from an array.
function doActionOnRemoveStringFromFileName($strString, $directory) {
if ($handle = opendir($directory)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
if(!strstr($file,$strString)) {
continue;
}
$newfilename = str_replace($strString,"",$file);
rename($directory . $file,$directory . $newfilename);
}
}
closedir($handle);
}
}
It works partially good. But the mistake what in this routine is, renaming action also takes on file's extensions. What i need is, Only to rename the file and it should not to be affect its file extensions. Any suggestions please. Thanks in advance :).
I have libraries written by myself that have some of those functions. Look:
//Returns the filename but ignores its extension
function getFileNameWithOutExtension($filename) {
$exploded = explode(".", $filename);
array_pop($exploded);
//Included a DOT as parameter in implode so, in case the
//filename contains DOT
return implode(".", $exploded);
}
//Returns the extension
function getFileExtension($file) {
$exploded = explode(".", $file);
$ext = end($exploded);
return $ext;
}
So you use
$replacedname = str_replace($strString,"", getFileNameWithOutExtension($file));
$newfilename = $replacedname.".".getFileExtension($file);
Check it working here:
http://codepad.org/CAKdCAA0

read files insert text into mysql

myFolderi have thousands of image files that have keyword text for the name. i am trying to read from the list of images and upload the text into a dB field. the problem is that some of the text has utf8 characters like l’Été that show up like this ��t�
how can i read foreign characters so that the accents will insert into the dB field?
this is how im handling it now
function ListFiles($dir) {
if($dh = opendir($dir)) {
$files = Array();
$inner_files = Array();
while($file = readdir($dh)) {
if($file != "." && $file != ".." && $file[0] != '.') {
if(is_dir($dir . "/" . $file)) {
$inner_files = ListFiles($dir . "/" . $file);
if(is_array($inner_files)) $files = array_merge($files, $inner_files);
} else {
array_push($files, $dir . "/" . $file);//$dir = directory name
//array_push($files, $dir);
}
}
}
closedir($dh);
return $files;
}
}
foreach (ListFiles('../../myDirectory') as $key=>$file){
//$file = preg_replace( '#[^\0-\x80]#u',"", $file );
echo $file ."<br />";
}
this is producing the same result
$str = "l’Été";
utf8_decode($str);
echo $str;
This solution may work for you, it will loop through all files in a directoy and then recursivly through any directories found until it ends up with a massive array of files.
Ive added some points you may wish to change, eg either mutli or single dimension arrays ( all depend on if you may want to maintain the folder structure.
and also if you want the file extention to be saved when you save the file name to db.
Code
function recursive_search_dir($dir) {
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if (in_array($file,array(".","..")))
continue; // We dont want to do anything with parent / current directory.
if (is_dir($file)) {
$result[] = recursive_search_dir($file); // Multi-dimension
# OR
array_merge($result,recursive_search_dir($file));// Single-dimension if you dont care about folder structure.
} else {
$result[] = utf8_decode($file); // full file name ( includes extention )
# OR
$result[] = utf8_decode(filename($file,PATHINFO_FILENAME)); // if you only want to capture the name and not the extention.
}
}
closedir($handle);
}
return $result;
}
$files = recursive_search_dir("."); // recursively searcht the current directory.

PHP Regular expression to find images beginning with _

I have a function that loads all image files it finds in the wordpress uploads directory. I'd like to modify it slightly so that it skips over any image that begins with an underscore character, "_someimage.jpg" is skipped, while "someimage.jpg is not...
Here is the existing function....
$dir = 'wp-content/uploads/';
$url = get_bloginfo('url').'/wp-content/uploads/';
$imgs = array();
if ($dh = opendir($dir))
{
while (($file = readdir($dh)) !== false)
{
if (!is_dir($file) && preg_match("/\.(bmp|jpeg|gif|png|jpg|)$/i", $file))
{
array_push($imgs, $file);
}
}
closedir($dh);
} else {
die('cannot open ' . $dir);
}
You can modify your current regex or add an boolean expression using strstr (which I'd recommend).
Modifying your current regex:
"/^[^_].*\.(bmp|jpeg|gif|png|jpg)$/i"
Or a simple expression to detect underscores in the string would be:
strstr($file, '_')
edit: and actually you could use substr:
substr($file, 0, 1) != '_'
if (!is_dir($file) && preg_match("/\.(bmp|jpeg|gif|png|jpg|)$/i", $file))
could be transformed into:
if (!is_dir($file) && preg_match("/^[^_].*\.(bmp|jpeg|gif|png|jpg|)$/i", $file))

How can I change a file's extension using PHP?

How can I change a file's extension using PHP?
Ex: photo.jpg to photo.exe
In modern operating systems, filenames very well might contain periods long before the file extension, for instance:
my.file.name.jpg
PHP provides a way to find the filename without the extension that takes this into account, then just add the new extension:
function replace_extension($filename, $new_extension) {
$info = pathinfo($filename);
return $info['filename'] . '.' . $new_extension;
}
substr_replace($file , 'png', strrpos($file , '.') +1)
Will change any extension to what you want. Replace png with what ever your desired extension would be.
Replace extension, keep path information
function replace_extension($filename, $new_extension) {
$info = pathinfo($filename);
return ($info['dirname'] ? $info['dirname'] . DIRECTORY_SEPARATOR : '')
. $info['filename']
. '.'
. $new_extension;
}
You may use the rename(string $from, string $to, ?resource $context = null) function.
Once you have the filename in a string, first use regex to replace the extension with an extension of your choice. Here's a small function that'll do that:
function replace_extension($filename, $new_extension) {
return preg_replace('/\..+$/', '.' . $new_extension, $filename);
}
Then use the rename() function to rename the file with the new filename.
Just replace it with regexp:
$filename = preg_replace('"\.bmp$"', '.jpg', $filename);
You can also extend this code to remove other image extensions, not just bmp:
$filename = preg_replace('"\.(bmp|gif)$"', '.jpg', $filename);
For regex fans,
modified version of Thanh Trung's 'preg_replace' solution that will always contain the new extension (so that if you write a file conversion program, you won't accidentally overwrite the source file with the result) would be:
preg_replace('/\.[^.]+$/', '.', $file) . $extension
Better way:
substr($filename, 0, -strlen(pathinfo($filename, PATHINFO_EXTENSION))).$new_extension
Changes made only on extension part. Leaves other info unchanged.
It's safe.
You could use basename():
$oldname = 'path/photo.jpg';
$newname = (dirname($oldname) ? dirname($oldname) . DIRECTORY_SEPARATOR : '') . basename($oldname, 'jpg') . 'exe';
Or for all extensions:
$newname = (dirname($oldname) ? dirname($oldname) . DIRECTORY_SEPARATOR : '') . basename($oldname, pathinfo($path, PATHINFO_EXTENSION)) . 'exe';
Finally use rename():
rename($oldname, $newname);
Many good answers have been suggested. I thought it would be helpful to evaluate and compare their performance. Here are the results:
answer by Tony Maro (pathinfo) took 0.000031040740966797 seconds. Note: It has the drawback for not including full path.
answer by Matt (substr_replace) took 0.000010013580322266 seconds.
answer by Jeremy Ruten (preg_replace) took 0.00070095062255859 seconds.
Therefore, I would suggest substr_replace, since it's simpler and faster than others.
Just as a note, There is the following solution too which took 0.000014066696166992 seconds. Still couldn't beat substr_replace:
$parts = explode('.', $inpath);
$parts[count( $parts ) - 1] = 'exe';
$outpath = implode('.', $parts);
I like the strrpos() approach because it is very fast and straightforward — however, you must first check to ensure that the filename has any extension at all. Here's a function that is extremely performant and will replace an existing extension or add a new one if none exists:
function replace_extension($filename, $extension) {
if (($pos = strrpos($filename , '.')) !== false) {
$filename = substr($filename, 0, $pos);
}
return $filename . '.' . $extension;
}
I needed this to change all images extensions withing a gallery to lowercase. I ended up doing the following:
// Converts image file extensions to all lowercase
$currentdir = opendir($gallerydir);
while(false !== ($file = readdir($currentdir))) {
if(strpos($file,'.JPG',1) || strpos($file,'.GIF',1) || strpos($file,'.PNG',1)) {
$srcfile = "$gallerydir/$file";
$filearray = explode(".",$file);
$count = count($filearray);
$pos = $count - 1;
$filearray[$pos] = strtolower($filearray[$pos]);
$file = implode(".",$filearray);
$dstfile = "$gallerydir/$file";
rename($srcfile,$dstfile);
}
}
This worked for my purposes.

Categories