PHP CLI: Recursive Search and Replace: Difference between revisions

Jump to navigation Jump to search
m
Reverted edits by Upazixorys (Talk); changed back to last version by Ric
No edit summary
m (Reverted edits by Upazixorys (Talk); changed back to last version by Ric)
 
Line 1: Line 1:
=[http://aluxyxenud.co.cc This Page Is Currently Under Construction And Will Be Available Shortly, Please Visit Reserve Copy Page]=
{{Uc nav PHP CLI}}
{{Uc nav PHP CLI}}
'''''PHP CLI Recursive Search and Replace'''''
'''''PHP CLI Recursive Search and Replace'''''
Line 14: Line 13:
|-
|-
|
|
'''''Run.bat'''''|| 
'''''Run.bat'''''|| 
|-valign="top"
|-valign="top"
|
|
<pre>
<pre>
TITLE CLI TEST BAT
TITLE CLI TEST BAT
COLOR B0
COLOR B0
Line 26: Line 25:
echo.
echo.
pause
pause
&lt;/pre&gt;
</pre>
|
|
&lt;br&gt;
<br>
Batch file to run test_1.php script
Batch file to run test_1.php script


Line 37: Line 36:
All scripts on this page will require the above change.
All scripts on this page will require the above change.
|-
|-
|'''''test_1.php'''''||&amp;nbsp;
|'''''test_1.php'''''||&nbsp;
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
&lt;?php
<?php
$sfolder = &quot;./usr/local/mysql&quot;;        // Start folder
$sfolder = "./usr/local/mysql";        // Start folder


$Array=recur_dir($sfolder);            // Retrieve file list
$Array=recur_dir($sfolder);            // Retrieve file list


foreach($Array as $line){              // Print list
foreach($Array as $line){              // Print list
  echo $line.&quot;\n&quot;;
  echo $line."\n";
}
}


Line 65: Line 64:
//========================================== END Recursive Directory =====
//========================================== END Recursive Directory =====
exit(0);
exit(0);
?&gt;
?>
&lt;/pre&gt;
</pre>
|
|
* First line sets the initial starting folder in variable '''$sfolder'''
* First line sets the initial starting folder in variable '''$sfolder'''
Line 74: Line 73:
* The recursive function takes as parameter the starting directory '''$dir'''  
* The recursive function takes as parameter the starting directory '''$dir'''  
* opendir() opens a handle to the starting directory and saves it in variable $dirlist  
* opendir() opens a handle to the starting directory and saves it in variable $dirlist  
* readdir() function returns a single entry from the currently open directory and saves it in variable $file.&lt;br&gt;'''''Note'':''' The returned value is either name of a directory or name of a file including its file extension.
* readdir() function returns a single entry from the currently open directory and saves it in variable $file.<br>'''''Note'':''' The returned value is either name of a directory or name of a file including its file extension.
* The while loop is use to read every single entry in the open directory until there are no more entries to read.
* The while loop is use to read every single entry in the open directory until there are no more entries to read.
* Inside the while loop the full path is assembled and assigned to variable '''$newpath'''. This is added to the array '''$Array[]'''
* Inside the while loop the full path is assembled and assigned to variable '''$newpath'''. This is added to the array '''$Array[]'''
Line 81: Line 80:
Run the batch file (double click on '''Run.bat''') Result as follows:
Run the batch file (double click on '''Run.bat''') Result as follows:
{|
{|
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
./usr/local/mysql/.
./usr/local/mysql/.
./usr/local/mysql/..
./usr/local/mysql/..
Line 91: Line 90:
./usr/local/mysql/share
./usr/local/mysql/share
Press any key to continue . . .
Press any key to continue . . .
&lt;/pre&gt;
</pre>
|
|
&lt;br&gt;
<br>
'''Well!''' What should be obvious there is no recursion, the code is only a starting point.
'''Well!''' What should be obvious there is no recursion, the code is only a starting point.


The output contains a mixture of folders (bin, data, share) and files (my.cnf, mysqlrun.bat, mysqlstop.bat, README.txt)
The output contains a mixture of folders (bin, data, share) and files (my.cnf, mysqlrun.bat, mysqlstop.bat, README.txt)


You will notice there are two special sub-directory names [.] and [..] these are normally hidden note that every folder contains them. A single period [.] means &quot;the current default directory.&quot; Two periods [..] means &quot;the directory which contains the current default directory&quot; also known as the parent directory. They are useful for navigation however will cause problems if not removed from a directory listing.   
You will notice there are two special sub-directory names [.] and [..] these are normally hidden note that every folder contains them. A single period [.] means "the current default directory." Two periods [..] means "the directory which contains the current default directory" also known as the parent directory. They are useful for navigation however will cause problems if not removed from a directory listing.   


|}
|}
Line 111: Line 110:
{|
{|
|-
|-
|'''''test_1.php'''''||&amp;nbsp;
|'''''test_1.php'''''||&nbsp;
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
&lt;?php
<?php
$sfolder = &quot;./usr/local/mysql&quot;;        // Start folder
$sfolder = "./usr/local/mysql";        // Start folder
$Array=recur_dir($sfolder);            // Retrieve file list
$Array=recur_dir($sfolder);            // Retrieve file list


foreach($Array as $line){              // Print list
foreach($Array as $line){              // Print list
  echo $line.&quot;\n&quot;;
  echo $line."\n";
}
}
//=== Recursive Directory ==============================================
//=== Recursive Directory ==============================================
Line 128: Line 127:
   $dirlist = opendir($dir);            // Open start directory
   $dirlist = opendir($dir);            // Open start directory
   while ($file = readdir($dirlist)){    // Iterate through list
   while ($file = readdir($dirlist)){    // Iterate through list
     if ($file != '.' &amp;&amp; $file != '..'){ // Skip if . or ..
     if ($file != '.' && $file != '..'){ // Skip if . or ..
       $newpath = $dir.'/'.$file;        // Create path. Either dir or file  
       $newpath = $dir.'/'.$file;        // Create path. Either dir or file  


Line 145: Line 144:
//========================================== END Recursive Directory =====
//========================================== END Recursive Directory =====
exit(0);
exit(0);
?&gt;
?>
&lt;/pre&gt;
</pre>
|
|
* Within the while loop first check for one of the special sub-folders. If not either of these contue otherwise skip. Let the while loop pick up another entry.
* Within the while loop first check for one of the special sub-folders. If not either of these contue otherwise skip. Let the while loop pick up another entry.
Line 155: Line 154:
* Handle is closed using closedir($dirlist) and array returned to caller.  
* Handle is closed using closedir($dirlist) and array returned to caller.  
'''''Run''''' the batch file (double click on '''Run.bat''') Result as follows:
'''''Run''''' the batch file (double click on '''Run.bat''') Result as follows:
&lt;pre&gt;
<pre>
./udrive/usr/local/mysql/my.cnf
./udrive/usr/local/mysql/my.cnf
&lt;/pre&gt;
</pre>
'''''Well what a pain''!'''
'''''Well what a pain''!'''


Line 168: Line 167:
=== Modification ===
=== Modification ===
{|
{|
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
  if (is_dir($newpath)){        // Is it a folder
  if (is_dir($newpath)){        // Is it a folder
   recur_dir($newpath);        // yes: Repeat this function
   recur_dir($newpath);        // yes: Repeat this function
   echo &quot;Path = &quot;.$newpath.&quot;\n&quot;;
   echo "Path = ".$newpath."\n";
  }                              // for that new folder
  }                              // for that new folder
&lt;/pre&gt;
</pre>
|
|
&lt;br&gt;
<br>
Add the '''echo''' line as shown to the above script.
Add the '''echo''' line as shown to the above script.


Line 187: Line 186:
=== Result ===
=== Result ===
{|
{|
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>


Path = ./usr/local/mysql/bin
Path = ./usr/local/mysql/bin
Line 202: Line 201:


Press any key to continue . . .
Press any key to continue . . .
&lt;/pre&gt;
</pre>
|
|
&lt;br&gt;
<br>
An interesting result, it clearly shows recursion is taking place.
An interesting result, it clearly shows recursion is taking place.


Line 229: Line 228:
{|
{|
|-
|-
|'''''test_1.php'''''||&amp;nbsp;
|'''''test_1.php'''''||&nbsp;
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
&lt;?php
<?php
$sfolder = &quot;./usr/local/mysql&quot;;  // Start folder
$sfolder = "./usr/local/mysql";  // Start folder
$Array=recur_dir($sfolder);            // Retrieve file list
$Array=recur_dir($sfolder);            // Retrieve file list


foreach($Array as $line){              // Print list
foreach($Array as $line){              // Print list
  echo $line.&quot;\n&quot;;
  echo $line."\n";
}
}
//=== Recursive Directory ==============================================
//=== Recursive Directory ==============================================
    
    
function recur_dir($dir,&amp;$Array){
function recur_dir($dir,&$Array){


   $dirlist = opendir($dir);            // Open start directory
   $dirlist = opendir($dir);            // Open start directory
   while ($file = readdir($dirlist)){    // Iterate through list
   while ($file = readdir($dirlist)){    // Iterate through list
     if ($file != '.' &amp;&amp; $file != '..'){ // Skip if . or ..
     if ($file != '.' && $file != '..'){ // Skip if . or ..
       $newpath = $dir.'/'.$file;        // Create path. Either dir or file  
       $newpath = $dir.'/'.$file;        // Create path. Either dir or file  


Line 263: Line 262:
//========================================== END Recursive Directory =====
//========================================== END Recursive Directory =====
exit(0);
exit(0);
?&gt;
?>
&lt;/pre&gt;
</pre>
|
|
&lt;br&gt;
<br>
'''''Run''''' the batch file (double click on '''Run.bat''') Result as follows:
'''''Run''''' the batch file (double click on '''Run.bat''') Result as follows:


Line 276: Line 275:


We have seen this [[PHP CLI: User Input#Function variable parameters |'''before''']] the solution is to change this line:
We have seen this [[PHP CLI: User Input#Function variable parameters |'''before''']] the solution is to change this line:
&lt;pre&gt;
<pre>
function recur_dir($dir,&amp;$Array){
function recur_dir($dir,&$Array){
&lt;/pre&gt;
</pre>
'''To:'''
'''To:'''
&lt;pre&gt;
<pre>
function recur_dir($dir,&amp;$Array=false){
function recur_dir($dir,&$Array=false){
&lt;/pre&gt;
</pre>


Initial call to function pass a single parameter.
Initial call to function pass a single parameter.
Line 301: Line 300:
|-
|-
|
|
&lt;pre&gt;
<pre>
'/(\.txt|\.cnf|\.conf)/'
'/(\.txt|\.cnf|\.conf)/'
&lt;/pre&gt;
</pre>
|
|
Pattern is delimited using ''''/'''' The entire regex is enclosed between brackets allowing the vertical bar (special character meaning or) to be used. The period (full stop) is a special regex character hence requires escaping using a backslash.     
Pattern is delimited using ''''/'''' The entire regex is enclosed between brackets allowing the vertical bar (special character meaning or) to be used. The period (full stop) is a special regex character hence requires escaping using a backslash.     
Line 312: Line 311:
{|
{|
|-
|-
|'''''test_1.php'''''||&amp;nbsp;
|'''''test_1.php'''''||&nbsp;
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
&lt;?php
<?php
$sfolder = &quot;./usr/local&quot;;              // Start folder
$sfolder = "./usr/local";              // Start folder
$File_list_array=recur_dir($sfolder);  // Retrieve file list
$File_list_array=recur_dir($sfolder);  // Retrieve file list


foreach($File_list_array as $line){    // Print list
foreach($File_list_array as $line){    // Print list
  echo $line.&quot;\n&quot;;
  echo $line."\n";
}
}
//=== Recursive Directory ==============================================
//=== Recursive Directory ==============================================
    
    
function recur_dir($dir,&amp;$Array=false){
function recur_dir($dir,&$Array=false){
   $f_str='/(\.txt|\.cnf|\.conf)/';        // Filter, required files
   $f_str='/(\.txt|\.cnf|\.conf)/';        // Filter, required files


Line 331: Line 330:


   while ($file = readdir($dirlist)){      // Iterate through list
   while ($file = readdir($dirlist)){      // Iterate through list
     if ($file != '.' &amp;&amp; $file != '..'){    // Skip if . or ..
     if ($file != '.' && $file != '..'){    // Skip if . or ..
       $newpath = $dir.'/'.$file;          // Create path. Either dir or file  
       $newpath = $dir.'/'.$file;          // Create path. Either dir or file  


Line 350: Line 349:
//========================================== END Recursive Directory =====
//========================================== END Recursive Directory =====
exit(0);
exit(0);
?&gt;
?>
&lt;/pre&gt;
</pre>
|
|
* '''''Run''''' the batch file (double click on '''Run.bat''')
* '''''Run''''' the batch file (double click on '''Run.bat''')
* '''Result''' Only files with the specified extensions are listed.
* '''Result''' Only files with the specified extensions are listed.
&lt;pre&gt;
<pre>
/(\.txt|\.cnf|\.conf)/
/(\.txt|\.cnf|\.conf)/
&lt;/pre&gt;
</pre>


''Note 1'': The Start folder was moved allowing more folders to be to searched. Outside of the function changed $Array to $File_list_array to avoid confusion.
''Note 1'': The Start folder was moved allowing more folders to be to searched. Outside of the function changed $Array to $File_list_array to avoid confusion.


'''''Note 2'':''' The array is passed to the function using the '''and''' operator '''&amp;'''$Array=false referred to as passing by pointer. It looks a little odd the array name is a pointer, however the array is not created until a value is assigned to it. If its not created it cannot be passed to the function for recursion. What the '''&amp;''' operator does is to create a variable to hold a pointer to the array. This will be created when the function is first called.       
'''''Note 2'':''' The array is passed to the function using the '''and''' operator '''&'''$Array=false referred to as passing by pointer. It looks a little odd the array name is a pointer, however the array is not created until a value is assigned to it. If its not created it cannot be passed to the function for recursion. What the '''&''' operator does is to create a variable to hold a pointer to the array. This will be created when the function is first called.       
   
   
File filtering is performed using preg_match() if a match found save the file to $Array
File filtering is performed using preg_match() if a match found save the file to $Array
&lt;pre&gt;
<pre>
  if (preg_match($f_str, $newpath)){  
  if (preg_match($f_str, $newpath)){  
   $Array[]= $newpath;             
   $Array[]= $newpath;             
  }                                 
  }                                 
&lt;/pre&gt;
</pre>


'''''Complete'':''' Essentially that completes the recursive file search template. You can now add replace code either externally to the function or convert it to perform both search and replace.
'''''Complete'':''' Essentially that completes the recursive file search template. You can now add replace code either externally to the function or convert it to perform both search and replace.
|}
|}
Result of running the above script
Result of running the above script
&lt;pre&gt;
<pre>
./usr/local/apache2/conf/httpd.conf
./usr/local/apache2/conf/httpd.conf
./usr/local/apache2/conf/ssl.conf
./usr/local/apache2/conf/ssl.conf
./usr/local/apache2/LICENSE.txt
./usr/local/apache2/LICENSE.txt
./usr/local/mysql/my.cnf
./usr/local/mysql/my.cnf
&lt;/pre&gt;
</pre>


Press any key to continue . . .
Press any key to continue . . .
Line 387: Line 386:
{|
{|
|-
|-
|'''''test_1.php'''''||&amp;nbsp;
|'''''test_1.php'''''||&nbsp;
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
&lt;?php
<?php
$s_str = '/\nListen\s\d+/';              // String to search for
$s_str = '/\nListen\s\d+/';              // String to search for
$r_str = &quot;\nListen 8080&quot;;                // Replacement string
$r_str = "\nListen 8080";                // Replacement string


$sfolder = &quot;./usr/local&quot;;                // Start folder
$sfolder = "./usr/local";                // Start folder
$File_list_array=recur_dir($sfolder);    // Retrieve file list
$File_list_array=recur_dir($sfolder);    // Retrieve file list


Line 412: Line 411:
//=== Recursive Directory ==============================================
//=== Recursive Directory ==============================================
    
    
function recur_dir($dir,&amp;$Array=false){
function recur_dir($dir,&$Array=false){
   $f_str='/(\.txt|\.cnf|\.conf)/';        // Filter, required files
   $f_str='/(\.txt|\.cnf|\.conf)/';        // Filter, required files


Line 418: Line 417:


   while ($file = readdir($dirlist)){      // Iterate through list
   while ($file = readdir($dirlist)){      // Iterate through list
     if ($file != '.' &amp;&amp; $file != '..'){    // Skip if . or ..
     if ($file != '.' && $file != '..'){    // Skip if . or ..
       $newpath = $dir.'/'.$file;          // Create path. Either dir or file  
       $newpath = $dir.'/'.$file;          // Create path. Either dir or file  


Line 437: Line 436:
//========================================== END Recursive Directory =====
//========================================== END Recursive Directory =====
exit(0);
exit(0);
?&gt;
?>
&lt;/pre&gt;
</pre>
|
|
To perform a global search and replace:
To perform a global search and replace:
Line 463: Line 462:
{|
{|
|-
|-
|'''''test_1.php'''''||&amp;nbsp;
|'''''test_1.php'''''||&nbsp;
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
&lt;?php
<?php
$start_dir  = './usr/local';            // Start folder
$start_dir  = './usr/local';            // Start folder
$file_type  = '/(\.txt|\.cnf|\.conf)/';  // Filter, required files
$file_type  = '/(\.txt|\.cnf|\.conf)/';  // Filter, required files
$search_str  = '/\nListen\s\d+/';        // String to search for
$search_str  = '/\nListen\s\d+/';        // String to search for
$replace_str = &quot;\nListen 8080&quot;;          // Replacement string
$replace_str = "\nListen 8080";          // Replacement string


if(file_sr_global($start_dir,$file_type,$search_str,$replace_str)){
if(file_sr_global($start_dir,$file_type,$search_str,$replace_str)){
  echo &quot;\n Search and replace complete\n&quot;;
  echo "\n Search and replace complete\n";
}
}


Line 484: Line 483:


   while ($file = readdir($dirlist)){          // Iterate through list
   while ($file = readdir($dirlist)){          // Iterate through list
     if ($file != '.' &amp;&amp; $file != '..'){        // Skip if . or ..
     if ($file != '.' && $file != '..'){        // Skip if . or ..
       $newpath = $start_dir.'/'.$file;        // Create path. Either dir or file  
       $newpath = $start_dir.'/'.$file;        // Create path. Either dir or file  


Line 503: Line 502:
       fwrite($fh, $Data);                    // Write to file
       fwrite($fh, $Data);                    // Write to file
       fclose($fh);                            // close file handle
       fclose($fh);                            // close file handle
       echo $newpath.&quot;\n&quot;; //***** Delete this line ***************************
       echo $newpath."\n"; //***** Delete this line ***************************
       }                                       
       }                                       
       }
       }
Line 514: Line 513:


exit(0);
exit(0);
?&gt;
?>
&lt;/pre&gt;
</pre>
|
|
&lt;br&gt;
<br>
To perform a global search and replace:
To perform a global search and replace:
* Set a folder to start the search from
* Set a folder to start the search from
Line 529: Line 528:
'''$Array[]= $newpath;''' has been replaced there is no feedback hence this test line:
'''$Array[]= $newpath;''' has been replaced there is no feedback hence this test line:


'''echo $newpath.&quot;\n&quot;;''' displays files that have been searched.
'''echo $newpath."\n";''' displays files that have been searched.


After testing it can be removed.
After testing it can be removed.
Line 536: Line 535:
* '''''Run''''' the batch file (double click on '''Run.bat''')
* '''''Run''''' the batch file (double click on '''Run.bat''')
* '''Result''' Since it’s a powerful function I have restricted it to change only the '''Listen''' parameter in Apache’s configuration file. That said it '''still kills''' the server hence re-run script change this line:
* '''Result''' Since it’s a powerful function I have restricted it to change only the '''Listen''' parameter in Apache’s configuration file. That said it '''still kills''' the server hence re-run script change this line:
&lt;pre&gt;
<pre>
$replace_str = &quot;\nListen 8080&quot;;
$replace_str = "\nListen 8080";
&lt;/pre&gt;
</pre>
To:
To:
&lt;pre&gt;
<pre>
$replace_str = &quot;\nListen 80&quot;;
$replace_str = "\nListen 80";
&lt;/pre&gt;
</pre>
Alternatively you can open the file and change it.
Alternatively you can open the file and change it.


Line 554: Line 553:


{|
{|
|-valign=&quot;top&quot;
|-valign="top"
|
|
&lt;pre&gt;
<pre>
//=== Recursive File Search and replace  ==========================================
//=== Recursive File Search and replace  ==========================================
// Inputs:  $start_dir  Absolute or relative path to starting folder. Do not
// Inputs:  $start_dir  Absolute or relative path to starting folder. Do not
Line 563: Line 562:
//                      e.g.  $file_type = '/(\.txt|\.cnf|\.conf)/'  
//                      e.g.  $file_type = '/(\.txt|\.cnf|\.conf)/'  
//          $search_str  A regex patern e.g $search_str  = '/\nListen\s\d+/'
//          $search_str  A regex patern e.g $search_str  = '/\nListen\s\d+/'
//          $replace_str A plain text string e.g. $replace_str = &quot;\nListen 8080&quot;
//          $replace_str A plain text string e.g. $replace_str = "\nListen 8080"
//
//
// Output:  Returns true --- Need to add error checking
// Output:  Returns true --- Need to add error checking
Line 578: Line 577:


   while ($file = readdir($dirlist)){            // Iterate through list
   while ($file = readdir($dirlist)){            // Iterate through list
     if ($file != '.' &amp;&amp; $file != '..'){          // Skip if . or ..
     if ($file != '.' && $file != '..'){          // Skip if . or ..
       $newpath = $start_dir.'/'.$file;          // Create path. Either dir or file  
       $newpath = $start_dir.'/'.$file;          // Create path. Either dir or file  


Line 592: Line 591:
         fclose($fh);                            // Close file handle
         fclose($fh);                            // Close file handle


         $Data = preg_replace($search_str, $replace_str, $Data,-1,$count);// S &amp; R
         $Data = preg_replace($search_str, $replace_str, $Data,-1,$count);// S & R
         if($count){                            // Was a replacement made
         if($count){                            // Was a replacement made
           $fh = fopen($newpath, 'w');          // yes: Open file for write
           $fh = fopen($newpath, 'w');          // yes: Open file for write
           fwrite($fh, $Data);                  // Write new $Data to file
           fwrite($fh, $Data);                  // Write new $Data to file
           fclose($fh);                          // Close file handle
           fclose($fh);                          // Close file handle
           echo $newpath.&quot; Replaced &quot;.$count.&quot;\n&quot;; //***** Delete this line *******
           echo $newpath." Replaced ".$count."\n"; //***** Delete this line *******
         }
         }
       }                                       
       }                                       
Line 608: Line 607:
}                                               
}                                               
//=================================== END Recursive File Search and replace  ======
//=================================== END Recursive File Search and replace  ======
&lt;/pre&gt;
</pre>
|}
|}
OK its true I never practice what I preach.
OK its true I never practice what I preach.

Navigation menu