简体   繁体   中英

PHP How can I iterate over a directory and merge all files that end with same string in a single file of that name

Description:

I have a directory that contains a large number of files named as follows:

2013_11_weekly.csv 
2013_10_weekly.csv 
2013_08_weekly.csv 
2013_09_weekly.csv 
2013_11_any_string.csv 
2013_10_any_string.csv

Problem:

How can I iterate over the directory and merge all the files that end with the same string into single files?

The end result would be a directory containing the following files.

weekly.csv 
any_string.csv 
...

Research:

I have the following code snippet that merges all all files.

<?php

$files = glob("*.csv");
$out = fopen("merged_files.csv", "w");
foreach($files as $file){
    fwrite($out, file_get_contents($file));
}
fclose($out);
echo "files merged";

?>

How can I amend my script to achieve the above?

I know I may have to use an array function, a str_ function and possibly a regular expression function.

Try this - it assumes the rules to grouping files (2013_[two-digits]_[grouping_string]). Nice trick is using ?P sign in regexp, which will put the aggregation string into $maches array under 'string_aggr' key:

$filenameRegexp = '/2013_[0-9]{2}_(?P<string_aggr>.+)\.csv/';
foreach (glob('*.csv') as $filename) {
   if (preg_match($filenameRegexp, $filename, $matches)) {
      $aggrFilename = $matches['string_aggr'] '.csv';
      file_put_contents($aggrFilename, file_get_contents(filename), FILE_APPEND);
   }
}

What it does is basically:

  1. Find all files matching the pattern '*.csv';
  2. Take each file and check if it matches pattern "2013_[two-digits]_[anything].csv"
  3. If it does match the pattern - get it's contents, and append it to the end of the file named "anything.csv".

After running it you should get desired results - multiple files with aggregated contents, according to those "anything" parts, in your case: weekly, any_string etc.

This is very simple, you must just figure out, how to fetch common name from filenames.

In my example, I split filename on 8th position ( 2013_11_weekly.csv becomes weekly.csv ):

$files = glob("*.csv");
$out = array();
foreach($files as $file) {
    $name = substr(basename($file), 8);
    if (!isset($out[$name])) {
        $out[$name] = fopen($name, "w");
    }
    fwrite($out[$name], file_get_contents($file));
}
foreach ($out as $f) {
    fclose($f);
}

It may be helpful for you. If you not getting your proper answer than let me know. merging multiple csv files using php

You can do an array, concatenate all values into array and then create those files

For example :

$files = glob("*.csv");
$files_content = array();

//parse all your files
foreach($files as $file){
    //get the suffix (ie '_weekly')
    $filename_end = substr(basename($file), 8);
    if(!isset($files_content[$file])) $files_content[$file] = "";
    //concatenate strings
    $files_content[$file] .= file_get_contents($file);
}

//and then create those files
foreach($fields_content as $filename => $content){
    $out = fopen($filename, "w");
    fwrite($out, $content);
    fclose($out);
}

Instead of fwrite, you should use file_put_content . This function is able to append data to a file.

Description

int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )

This function is identical to calling fopen(), fwrite() and fclose() successively to write data to a file.

If filename does not exist, the file is created. Otherwise, the existing file is overwritten, unless the FILE_APPEND flag is set.

resulting in code like (not tested, just for understanding):

<?php
$files = glob("*.csv");
foreach($files as $file){
    // get substring 6 chars before the last 4 chars (.csv)
    $type = substr($file, -4, -10)
    // switch based on the substring $type
    switch($type) {
        case "weekly":
            file_put_content("merged_files_weekly.csv", file_get_contents($file), FILE_APPEND);
        break;
        case "string" :
            file_put_content("merged_any_string.csv", file_get_contents($file), FILE_APPEND);
        break;
        default:
            // do nothing
        break;
    }

}
echo "files merged";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM