help collect from 2 files csv - one. To merge similar cell. An example is shown below, and part of my code.
I would be very grateful for the help and thanks in advance
csv1.csv =
name;price
Tom;1000
Anna;2000
Aleks;3000
Maikal;2000
Piter;5000
csv2.csv =
name;price
Tom;1200
Anna;2300
Andre;2000
Maikal2;2400
all.csv - The resulting file.
name;price;price
Aleks;3000;
Andre;;2000
Anna;2000;2300
Piter;5000;
Maikal;2000;
Maikal2;;2400
Tom;1000;1200
I have a script that simply glued file based on 1 line. But it gives a different result.
if(#$_FILES["DATAF_1"]["size"]>0 AND #$_FILES["DATAF_2"]["size"]>0)
{
$data=array();
function read_csv($file)
{
$out=array();
$lines = file($file);
foreach ($lines as $line_num => $line)
{
$out[]=explode(";",$line);
}
return $out;
}
function action_csv(&$array,$input)
{
for ($i=0; $i<count($input); $i++)
{
for ($i2=1; $i2<count($input[$i]); $i2++) {
if(trim($input[$i][0])!=""){$array[trim($input[$i][0])][]=trim($input[$i][$i2]);}
}
}
}
function form_csv($data)
{
$out=array();
foreach ($data as $line_num => $line)
{
$out[]=$line_num.";".implode(";",$line);
}
return implode("\r\n",$out);
}
$data1=read_csv($_FILES["DATAF_1"]["tmp_name"]);
$data2=read_csv($_FILES["DATAF_2"]["tmp_name"]);
action_csv($data,$data1);
action_csv($data,$data2);
#unlink("out.csv");
$fp = fopen ("out.csv", "w+");
fwrite ($fp, form_csv($data));
fclose ($fp);
I tried your code without the $_Files (just from the filesystem) and it works. So the Problem might be in the file uploade and not in the code you posted.
EDIT:
So now it should work as you wish:
function genAllIndexes(&$array,&$maxIndex){
foreach($array as &$line){
for($i = 0; $i < $maxIndex; $i++){
if(!isset($line[$i])){
$line[$i] = "";
}
}
ksort($line);
}
}
function action_csv(&$array,$input, &$counter){
for ($i=0; $i<count($input); $i++){
for ($i2=1; $i2<count($input[$i]); $i2++) {
if(trim($input[$i][0])!=""){
$array[trim($input[$i][0])][$counter]=trim($input[$i][$i2]);
}
}
}
$counter++;
}
$data1=read_csv('data1.csv');
$data2=read_csv('data2.csv');
$counter = 0;
action_csv($data,$data1, $counter);
action_csv($data,$data2, $counter);
genAllIndexes($data, $counter);
ksort($data);
#unlink("out.csv");
$fp = fopen ("out.csv", "w+");
fwrite ($fp, form_csv($data));
fclose ($fp);
Related
I couldn't find a solution to this. I'm sorry if this is a silly question.
I have 4 log files and I need to remove all log except last 10 lines.
I'm able to do it for 1 file but how to apply it on 4 files using once simple php code?
My current code:
<?php
$lines_array = file("log.txt");
$lines = count($lines_array);
$new_output = "";
for ($i=$lines - 10; $i < $lines; $i++) {
$new_output .= $lines_array[$i];
}
$filename = "log.txt";
file_put_contents($filename,$new_output);
What is the best way to achieve this?
Functional programming to the rescue:
function rotate(string $filename)
{
$lines_array = file($filename);
$lines = count($lines_array);
$new_output = "";
for ($i=$lines - 10; $i < $lines; $i++) {
$new_output .= $lines_array[$i];
}
file_put_contents($filename,$new_output);
}
rotate('log1.txt');
rotate('someOtherLog.txt');
rotate('third/log/file.txt);
//etc.
// or,
$logs = [
'log1.txt',
'someOtherLog.txt',
'third/log/file.txt'
];
foreach($logs as $file) {
rotate($file);
}
This allows you to write the code for rotating your logs one time, which makes your code better by being DRY (Don’t Repeat Yourself)
List your logfiles in an array, and loop over it, rewriting the log files as you go:
$logs = [
'log1.txt',
'log2.txt',
'log3.log'
];
foreach($logs as $log) {
// Only do this if we read the file.
if ($logData = file($log)) {
// array_slice takes a portion of the array
file_put_contents($log, array_slice($logData,-10));
}
}
Please try this code:
<?php
$fp = fopen("log.txt","ab+");
$data = fread($fp,filesize("log.txt"));
$data_array = explode("\n",$data);
$new_data = array();
for($i = count($data_array) - 1; $i >= count($data_array) - 10;$i--)
{
array_push($new_data , $data_array[$i]);
}
fclose($fp);
$new_data_array = array_reverse($new_data);
$data = implode("\n",$new_data_array);
$fp = fopen("log.txt","w");
fwrite($fp,$data);
fclose($fp);
?>
I'm trying to post 3 arrays using foreach and for some reason the break at the end isn't working and it outputs the whole list (40+) on to the page.
$file = fopen('names.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
shuffle($line);
$i = 0;
foreach ($line as $number) {
{
if($i==3){ break; } else {
$rtime = mt_rand(1, 7);
echo $number; }
$i++;
}
}
}
fclose($file);
This is kind of how it looks: take.ms/cLgIh, instead it should only show 3 of these usernames.
<?php
$i = 0;
//I have opened my contact.csv :P
$file = fopen('contact.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
shuffle($line);
foreach ($line as $number) {
{
if($i==3){ exit(); } else {
$rtime = mt_rand(1, 7);
echo "<br/> i = ".$i.$number.", "; }
}
$i++;
}
}
fclose($file);
?>
I have downloade first sample CSV from here:-http://www.sample-videos.com/download-sample-csv.php
And this code works for me:-
<?php
$file = fopen('SampleCSVFile_2kb.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
shuffle($line);
$i = 0;
foreach ($line as $number) {
if($i==3){
exit;
} else {
$rtime = mt_rand(1, 7);
echo $number.'<br/>';
echo $i.'<br/>'; // you can remove this line
}
$i++;
}
}
fclose($file);
?>
Output on each page refresh:-
http://prntscr.com/cln2ju
http://prntscr.com/cln2nf
Note:- if still not work then check your CSV file. May be it is corrupted.
Conclusion:- And after all discussion it comes to an end that your CSV file is corrupted. But yes code improvement is needed too
You need to increment $i otherwise it's value will always be 0
$i = 0;
foreach ($line as $number) {
$rtime = mt_rand(1, 7);
echo "$number";
if($i==3) break;
$i++;
}
Also you need to check if your while statement is closing
$file = fopen('names.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
shuffle($line);
$i = 0;
foreach ($line as $number) {
$rtime = mt_rand(1, 7);
echo $number;
if($i==3) break;
$i++;
}
} //check for this
As I can see in your code example it is missing the closing brace
Also, remove the double quotes from your $number, it's not necessary.
echo $number
You have a mistake is that the break are in the if($i==3) and you declared $i =0, but never increment this. So $i never arrive at 3.
I am attempting to assign the string returned by the fgets() function to an array in PHP. I have tried test strings and they work fine. I have also made sure that fgets() is returning items, but still no joy. Thinking that it may be a timing issue, I had the function run onload and that didn't work. My code is below; any help on this would be much appreciated.
function createDataArray()
{
global $resultsArray;
$i = 0;
$file = fopen("downloads/E0.csv","r");
while(! feof($file))
{
$line = fgets($file, 4096);
$resultsArray[$i] = $line; //This isn't working. Something is wrong with $line. It is a string, but it doesn't get assigned to the array.
$i = $i + 1;
}
fclose($file);
}
PLEASE return the array; do not use globals.
This fix should work:
function createDataArray()
{
$resultsArray = array();
$file = fopen("downloads/E0.csv","r");
while(! feof($file))
{
$line = fgets($file, 4096);
$resultsArray[] = $line;
}
fclose($file);
return $resultsArray;
}
I'm using a simple function to write write arrays to a CSV-file, which look like this:
function writeToCSV($array) {
$fp = fopen('programmes.csv', 'a');
fputcsv($fp, $array);
fclose($fp);
}
Simple as a pie. However, is there anyway to know what line-number the pointer is at? Because I want to be able to after 1000 lines to begin writing to a new file. Why? Because I need to be able to import them to a database later with some memory constraints, and to parse a CSV-file with 15000 lines is a no-no.
function writeToCSV($array) {
$i = 1;
$j = 1;
$fp = fopen('programmes' . $j . '.csv', 'a');
foreach($array as $fields) {
if ($i % 1000 == 0) {
fclose($fp);
$fp = fopen('programmes' . $j . '.csv', 'a');
$j = $j + 1;
}
fputcsv($fp, $fields);
$i = $i + 1;
}
fclose($fp);
}
Try this:
count(file('programmes.csv'));
This will give you the number of lines in a file.
I haven't tried if this works, but i would do something like this:
<?php
function writeToCSV($array) {
// count lines in the current file
$linecount = 0;
$fh = fopen('programmes.csv','rb') or die("ERROR OPENING DATA");
while (fgets($fh) !== false) $linecount++;
fclose($fh);
$aSize = sizeof($array);
if (($linecount + $aSize) > 1000) {
// split array
$limit = 1000 - $linecount;
$a = array_slice($array, 0, $limit);
$b = array_slice($array, $limit);
// write into first file
$fp = fopen('programmes.csv', 'a');
foreach($a as $field) fputcsv($fp, $field);
fclose($fp);
// write into second file
$fp = fopen('programmes2.csv', 'a');
foreach($b as $field) fputcsv($fp, $field);
fclose($fp);
} else {
$fp = fopen('programmes.csv', 'a');
$idx = 0;
while ($linecount < 1000) {
// fill the file to the 1000 lines
fputcsv($fp, $array[$idx]);
++$linecount;
++$idx;
}
fclose($fp);
if ($idx != $aSize) {
// create new file
$fp = fopen('programmes.csv', 'a');
while ($idx< $aSize) {
// fill the file to the 1000 lines
fputcsv($fp, $array[$idx]);
++$idx;
}
fclose($fp);
}
}
}
?>
I'm not sure if this is possible, I've been googling for a solution... But, essentially, I have a very large file, the lines of which I want to store in an array. Thus, I'm using file(), but is there a way to do that in batches? So that every,say, 100 lines it creates, it "pauses"?
I think there's likely to be something I can do with a foreach loop or something, but I'm not sure that I'm thinking about it the right way...
Like
$i=0;
$j=0;
$throttle=100;
foreach($files as $k => $v) {
if($i < $j+$throttle && $i > $j) {
$lines[] = file($v);
//Do some other stuff, like importing into a db
}
$i++;
$j++;
}
But, I think that won't really work because $i & $j will always be equal... Anyway, feeling muddled... Can someone help me think a lil' clearer?
Read the file in line by line for however many lines you need, appending each line to an array. When the array gets to the desired length, process it, and empty the array. E.g.:
$handle = #fopen("/tmp/inputfile.txt", "r");
$throttle = 100;
$data = array();
if ($handle) {
while(!feof($handle)) {
$buffer = fgets($handle, 4096);
$data[] = $buffer;
if(count($data) == $throttle) {
doSomething($data);
$data = array();
}
}
fclose($handle);
}
You never incremented $i or $j... What you can do, is something like:
$data = array();
$chunk = 100;
$f = fopen($file, 'r');
while (!feof($f)) {
for ($i = 0; $i < $chunk; $i++) {
$tmp = fgets($f);
if ($tmp !== false) {
$data[] = $tmp;
} else {
//No more data, break out of the inner loop
break;
}
}
//Process your data
$data = array();
}
fclose($f);
If by "pause", you mean that you really want to pause execution of your script, use sleep or some of its variants: http://php.net/manual/en/function.sleep.php