Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need help in changing file names 1

Status
Not open for further replies.

elentz

Technical User
Jan 9, 2007
81
US
I have several hundred files that are named in a way that will not work for the way I want to use them. We saved these files with filenames and now we want to change the names. For example the files were named with a 4 digit number. It was an account number for the customer that the file was associated with. Now we use the phone number when we save the file. So now I have several hundred files in the wrong naming convention. I have a list of the customer phone numbers and the account codes. What I am looking for is some way to rename the files using the list to remove the account number and replace it with the phone number. Can someone suggest a method of accomplishing this?
Thanks
 
This is a breeze in a something like VBS. PHP is not the correct solution.

assuming your account-to-phone number list looks something like:
Code:
2748, 5551234567
3452, 5559876543
8437, 5556784930
9276, 5551928374

this will do what you need.
Code:
set objFSO   = WScript.CreateObject("Scripting.FileSystemObject")
set objShell = WScript.CreateObject("WScript.Shell")
set objFiles = objFSO.GetFolder("C:\temp\phonelist").Files

strPhoneList = objFSO.OpenTextFile("c:\temp\phonelist\phonelist.txt").ReadAll

for each objFile in objFiles
	strAccount = left(objFile.Name, len(objFile.Name) - 4)
	intFound = inStr(strPhoneList, strAccount)
	if (intFound) then
		strPhoneNumber = mid(strPhoneList, intFound + 6, 10)
		objFile.Name = replace(objFile.Name, strAccount, strPhoneNumber)
	end if
next

-Geates
 
Thanks for the reply!

I tried your code and it almost worked. All my account codes are 4 digits long ie 14 is 0014 and 100 is 0100. All my phone numbers are xxx-yyy-vvvv format. So the code made most of the name changes but not quite it cut off some of the phone number info.

for the phone # would I change:
strPhoneNumber = mid(strPhoneList, intFound + 6, 10)

to:

strPhoneNumber = mid(strPhoneList, intFound + 6, 12) ?

For the account code I am lost.
 
Correct. The code defines strPhoneNumber as 10 chars. However, your "naming convention" introduces addition chars (-) between sets of numbers so, yes, strPhoneNumber = mid(strPhoneList, intFound + 6, 12).

As for the account name, are you saying that the account codes in the "account/phone number list" include the leading zeros and the file names don't)?

Code:
account: 0014
file name: 14.dat

Or the other way around

Code:
account: 14
file name: 0014.dat

-Geates
 
it's a breeze within php too! in fact i wrote something today to do exactly the same thing for a bunch of badly named tv shows.

Code:
<?php
define('COPY', true);// true will mean that the files are COPIED to their new name.  anything else will cause a rename
$dir = 'path/to/the/dir/you/want/to/change/'; //don't forget the trailing slash
$transforms = $files = array();
$function = (COPY === true) ? 'copy' : 'rename';

//open the directory and get the file names into memory
$dh = opendir($dir) or die ('cannot open directory');
while (false !== ($file = readdir($dh))){
	//we want to do this to avoid recursive reads
	if (!is_dir($file) && $file!='.' && $file!='..') $files[] = $file;
}
//close the directory
closedir($dh);
//now read in the cross table
//assume that the format is like this
//customerphonenumber TAB account code
$fh = fopen($crosstable);
$sep = "\t"; //change this if another separator is used
while ($row = fgets($fh)){
	list($phone, $code) = explode ($sep, $row);
	$transforms[$phone]=$code;
}
fclose($fh);
foreach ($files as $file){
	if (isset($transforms[$file])){
		$function ($dir.$file, $dir.$transforms[$file]);
	}
}
?>
 
apologies if it is not obvious. the $crosstable variable should point to the full path of the cross table. and the php process should have the requisite perms to read that table and write to the directory to have the rename run on its files.
 
Another way to do it! Thanks

Geates,

The format I have for the account code /Phone # is:

0014,989-631-1111

The file is named like 0014.axx
I can remove all the - in the phone number if that is causing problems.

Thanks
 
OK,
I removed all the - in the phone numbers, changed the str back to 10 and ran the script. It ran with no errors but didn't change any of the file names
 
I had the name of the phonelist as a .csv and I changed it to .txt I run the script and I get an error :

Line 12
Char 9
Error Bad File name or number
code 800A0034

The phone list is this format:
0019,9896311111

The filename is:
0019.axx

What could be wrong?

Here's the code:

set objShell = WScript.CreateObject("WScript.Shell")
set objFiles = objFSO.GetFolder("C:\test\db").Files

strPhoneList = objFSO.OpenTextFile("c:\test\Oldnumbers.txt").ReadAll

for each objFile in objFiles
strAccount = left(objFile.Name, len(objFile.Name) - 4)
intFound = inStr(strPhoneList, strAccount)
if (intFound) then
strPhoneNumber = mid(strPhoneList, intFound + 6, 10)
objFile.Name = replace(objFile.Name, strAccount, strPhoneNumber)
end if
next

Is my format wrong or something?
 
oops I missed the first line of the code:

set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
 
hmm.. it sounds like the objFile.Name contains an invalid character. Perhaps as comma? Throw a couple lines of debug code.
Code:
strFileName = replace(objFile.Name, strAccount, strPhoneNumber)
msgbox strFileName

if the filename contains a comma, adjust the strAccount line appropriately. Given the format of your phone list,
Code:
strPhoneNumber = mid(strPhoneList, intFound + 5, 10)

-Geates
 
now that you have given us more information about the cross table here is a php method. a few hundred files should take less than a second. it is also more efficient that the vbscript in that a read of the cross table is not necessitated for each file

Code:
<?php

define('COPY', true);// true will mean that the files are COPIED to their new name.  anything else will cause a rename
$dir = 'c:/test/db/; //don't forget the trailing slash
$crosstable = 'c:/test/Oldnumbers.txt';
$ext = '.axx';//file extension

$transforms = $files = array();
$function = (COPY === true) ? 'copy' : 'rename'; //change this as needed

//open the directory and get the file names into memory
$dh = opendir($dir) or die ('cannot open directory');
while (false !== ($file = readdir($dh))){
    //we want to do this to avoid recursive reads
    if (!is_dir($file) && $file!='.' && $file!='..') $files[] = basename($file, $ext);
}
//close the directory
closedir($dh);
//now read in the cross table
//assume that the format is like this
//customerphonenumber TAB account code
$fh = fopen($crosstable);
$sep = ","; //change this if another separator is used
while ($row = fgets($fh)){
	if (!empty($row)){
	    list($code, $phone) = explode ($sep, $row);
	    $transforms[$code]=trim($phone);
	}
}
fclose($fh);
foreach ($files as $file){
    if (isset($transforms[$file])){
        $function ($dir.$file.$ext, $dir.$transforms[$file].$ext);
    }
}
?>
 
jpadie,

Thanks for the PHP solution. I have a question. I am only at this time using a shared server on a linux system. My files are in a directory that is in my root. /dbtest and the crosstable is in my Apache along with the php script you provided. I tried using /dbtest/ for the location and I got "cannot open directory" Where did I go wrong?

Thanks
 
the relevant functions are making filesystem calls rather than http calls. so if you are addressing files in / this means they must be in the system root. it is very unlikely, on a shared server, that you have read/write (or any) access to the system root. i suspect the files are in the webroot in which case perhaps you could use relative url notation to point to the files if you are unable to find the full name of the directory?

or, if you want, to find the full canonical name of the root directory use this script

Code:
echo realpath(dirname(__FILE__));

save the script in the root directory and point your browser at it.
 
I found out what my path was and I changed it in the php script as such


$dir = '/home/communiq/public_html/dbtest/'; //don't forget the trailing slash
$crosstable = '/home/communiq/public_html/dbtest/Oldnumbers.txt';

The script and the Oldnumbers.txt file are in the same directory as all the files to be changed.

The script runs without errors but there are no changes to the files.

Thanks
 
Are you seeing this with both methods? If so, it's quite likely that you don't have the appropriate permissions to modify files or folders. The vbs runs flawlessly when I test it.

Data files
Code:
0014.axx
0520.axx
2748.axx

Phone / Account list
Code:
0014,5553728546
0520,5552345879
2748,5551234567

VBS
Code:
set objFSO   = WScript.CreateObject("Scripting.FileSystemObject")
set objShell = WScript.CreateObject("WScript.Shell")
set objFiles = objFSO.GetFolder("C:\temp\phonelist").Files

strPhoneList = objFSO.OpenTextFile("c:\temp\phonelist\phonelist.txt").ReadAll

for each objFile in objFiles
	strAccount = left(objFile.Name, len(objFile.Name) - 4)
	intFound = inStr(strPhoneList, strAccount)
	if (intFound) then
		strPhoneNumber = mid(strPhoneList, intFound + 5, 10)
		objFile.Name = replace(objFile.Name, strAccount, strPhoneNumber)
	end if
next
-Geates
 
to test for errors change my code as shown

Code:
foreach ($files as $file){
    if (isset($transforms[$file])){
        $r = $function ($dir.$file.$ext, $dir.$transforms[$file].$ext);
        [red]if (!$r){
         echo 'problem with file <br/><pre>' ; 
         print_r (error_get_last()); 
        }[/red]
    }
}
 
jpadie,

I now get a 500 server error even though I have all the files set as 0666. I made the change you suggested with no update in the names of the files. Anything else I can try?
 
Geates,

I got something wrong. Don't know what. I am still getting the vbs error Bad file name or number.
 
a 500 server error often means something is crashing your php installation. probably something to report to your host.

for the time being, simplify and footprint my script by changing to the following

Code:
<?php
ini_set ('display_errors',true);
error_reporting(E_ALL);

$dir = '/home/communiq/public_html/dbtest/'; //don't forget the trailing slash
$crosstable = '/home/communiq/public_html/dbtest/Oldnumbers.txt';
$ext = '.axx';//file extension

$transforms = $files = array();

if (!is_writable($dir)){
	die ('you do not have permission to write to the directory: ' . $dir);
}

//open the directory and get the file names into memory
$dh = opendir($dir) or die ('cannot open directory to read the current files');
while (false !== ($file = readdir($dh))){
    //we want to do this to avoid recursive reads
    if (!is_dir($file) && $file!='.' && $file!='..') $files[] = basename($file, $ext);
}
closedir($dh);  //close the directory
$fh = fopen($crosstable, 'rbt') or die ('cannot open the cross table file');
$sep = ","; //change this if another separator is used
while ($row = fgets($fh)){
    if (!empty($row)){
        list($code, $phone) = explode ($sep, $row);
        $transforms[$code]=trim($phone);
    }
}
fclose($fh); //close the file handle
foreach ($files as $file){
    if (isset($transforms[$file])){
    	echo "copying {$file}.{$ext} to $transforms[$file].$ext <br/>";
        $r = copy ($dir.$file.$ext, $dir.$transforms[$file].$ext);
		if (!$r){
			echo "Error copying {$file}.{$ext} to $transforms[$file].{$ext} <br/>";
		}
    }
}
?>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top