File manupulation search and replace csv php - php
I need a script that is finding and then replacing a sertain line in a CSV like file.
The file looks like this:
18:110327,98414,127500,114185,121701,89379,89385,89382,92223,89388,89366,89362,89372,89369
21:82297,79292,89359,89382,83486,99100
98:110327,98414,127500,114185,121701
24:82297,79292,89359,89382,83486,99100
Now i need to change the line 21.
This is wat i got so far.
The first 2 to 4 digits folowed by : ar a catergory number. Every number after this(followed by a ,) is a id of a page.
I acces te id's i want (i.e. 82297 and so on) from database.
//test 2
$sQry = "SELECT * FROM artikelen WHERE adviesprijs <>''";
$rQuery = mysql_query ($sQry);
if ( $rQuery === false )
{
echo mysql_error ();
exit ;
}
$aResult = array ();
while ( $r = mysql_fetch_assoc ($rQuery) )
{
$aResult[] = $r['artikelid'];
}
$replace_val_dirty = join(",",$aResult);
$replace_val= "21:".$replace_val_dirty;
// file location
$file='../../data/articles/index.lst';
// read the file index.lst
$file1 = file_get_contents($file);
//strip eerde artikel id van index.lst
$file3='../../data/articles/index_grp21.lst';
$file3_contents = file_get_contents($file3);
$file2 = str_replace($file3_contents, $replace_val, $file1);
if (file_exists($file)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
if (file_exists($file3)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
// replace the data
$file_val = $file2;
// write the file
file_put_contents($file, $file_val);
//write index_grp98.lst
file_put_contents($file3, $replace_val);
mail('info#', 'Aanbieding catergorie geupdate', 'Aanbieding catergorie geupdate');
Can anyone point me in the right direction to do this?
Any help would be appreciated.
You need to open the original file and go through each line. When you find the line to be changed, change that line.
As you can not edit the file while you do that, you write a temporary file while doing this, so you copy over line-by-line and in case the line needs a change, you change that line.
When you're done with the whole file, you copy over the temporary file to the original file.
Example Code:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
This part is just setting up the basics: The category, the IDs of the articles and then building the related strings.
Now opening the file to change the line in:
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
The file is locked so that no other process can edit the file while it gets changed. Next to that file, the temporary file is needed, too:
$temp = new SplTempFileObject(4096);
After setting up the two files, let's go over each line in $file and compare if it needs to be replaced:
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
Now the $temporary file contains already the changed line. Take note that I used UNIX type of EOF (End Of Line) character (\n), depending on your concrete file-type this may vary.
So now, the temporary file needs to be copied over to the original file. Let's rewind the file, truncate it and then write all lines again:
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
And finally you need to lift the lock:
$file->flock(LOCK_UN);
And that's it, in $file, the line has been replaced.
Example at once:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
$temp = new SplTempFileObject(4096);
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
$file->flock(LOCK_UN);
Should work with PHP 5.2 and above, I use PHP 5.4 array syntax, you can replace [111182297, ...] with array(111182297, ...) in case you're using PHP 5.2 / 5.3.
Related
How to remove a file when it's empty php?
I have multiple files. My script searches the file for the sequence name and the sequence. If it's found, the format is changed from gb to fasta and only the sequence name and sequence is kept and written back into the file. But sometimes the file doesn't contain a sequences name. In that case and I don't write anything into the file, the file is empty. This files should be removed because at the end of my script a multifasta is created from all these files. # Find all gb files $files = glob("*.gb"); foreach ($files as $filename){ $newname = basename($filename, ".gb"). ".fasta"; rename($filename, $newname); $condition = false; $lines = file($newname); foreach($lines as $line) { if (strstr($line, "ACCESSION") ) { # Find the line containing the sequence name $head = str_replace("ACCESSION ","",$line); $final = "> " . $head; # check if $head contains text if ($head == ""){ $condition = true; } } $sequence = trim($line); # Find the sequence and check the condition if (preg_match('/^\d/', $sequence) && $condition == false){ $sequence = preg_replace('/[0-9]+/', '', $sequence); $sequence = preg_replace('/\s/',"",$sequence); # Store in string $out .= $sequence; } } # Read lines into file $f = fopen($newname, "w"); fwrite($f, $t); fclose($f); } # Create multifasta exec('for f in *fasta; do cat "$f"; echo; done > db', $return); How could I best remove the file when it's empty so it wouldn't be inserted in the multifasta. I am sure it's something simple but I can't figure out how to do it.
The simplest way is to use the filesize command, I think: if (filesize ( $filename) === 0){ unlink ($filename); //This will delete the file. continue; //carry on with next file } The unlink command will generate an error message if it can't delete the file for whatever reason. I don't know if you need to check that.
Delete file specific file content between a characters using php [duplicate]
This question already has answers here: RegEx to remove /** */ and // ** **// php comments (3 answers) Closed 4 years ago. I need to delete a particular file content that is between these two characters /* & */ using PHP. The file from which I am trying to remove these comments is very large and includes a large data set, So optimized solution will be appreciated. Example content: /*SOME TEXT HERE */ 12314 So, the final file should contain only 1234 Here is the method that keeps on running until we got the comments string. Please note that the comments are only at one place in the file and they are always on the top of the file. Please let me know how can I delete those lines on which match the comments condition? Below is the method that I updated. $reading = fopen(public_path('file.csv'), 'r'); $writing = fopen(public_path('file.csv'), 'w'); $counter = 0; $line = ""; $no_of_lines = 0; while (!feof($reading) && $counter != 2) { $new_line = fgets($reading); if ($matched_string = strstr($new_line, "/*")) { $line = $line . $matched_string; $counter++; } elseif ($matched_string = strstr($new_line, "*/")) { $line = $line . $matched_string; $counter++; } else { $line = $line . $new_line; fwrite($writing, ""); } $no_of_lines++; } fclose($writing); fclose($reading);
First open the file but one line at a time to save memory: <?php $reading = fopen('myfile', 'r'); $writing = fopen('newfile', 'w'); while (!feof($reading)) { $line = fgets($reading); // We will put the removal logic in here fputs($writing, $line); } fclose($reading); fclose($writing); For the removal, use some regex. <?php $line = preg_replace('#\/\*.+\*\/#', '/* */', $line); You can see this working here https://3v4l.org/XmltD If you don't want the /* either, just change the replace call to this: $string = preg_replace('#\/\*.+\*\/#', '', $string);
Php code that returns an array with filenames of files which contains a string
Im trying to make a Php file that receives nothing and checks every file on the folder, searching for a string inside them. it echos a array of filenames that have the string inside. Any way to do it, possibly with low memory usage? Thank you a lot.
To achieve something like this, I recommend you read about the DirectoryIterator class, file_get_contents, and about strings in PHP. Here is an example of how you can read the contents of a a given directory ($dir) and use strstr to search for a specific string occurrence in each file's contents ($contents): <?php $dir = '.'; if (substr($dir, -1) !== '/') { $dir .= '/'; } $matchedFiles = []; $dirIterator = new \DirectoryIterator($dir); foreach ($dirIterator as $item) { if ($item->isDot() || $item->isDir()) { continue; } $file = realpath($dir . $item->getFilename()); // Skip this PHP file. if ($file === __FILE__) { continue; } $contents = file_get_contents($file); // Seach $contents for what you're looking for. if (strstr($contents, 'this is what I am looking for')) { echo 'Found something in ' . $file . PHP_EOL; $matchedFiles[] = $file; } } var_dump($matchedFiles); There is some extra code in this example (adding a trailing slash to $dir, skipping dot files and directories, skipping itself, etc.) that I encourage you to read and learn about.
<?php $folderPath = '/htdocs/stock/tae'; $searchString = 'php'; $cmd = "grep -r '$searchString' $folderPath"; $output = array(); $files = array(); $res = exec($cmd, $output); foreach ($output as $line) { $files[] = substr($line, 0, strpos($line, ':')); } print_r($files);
Unable to insert data in CSV file PHP
I am in process of inserting data in the desired CSV file from another CSV file. CSV file is creating fine with out any problem but its is not insert array data in file. It only inserts header on the first row. Below is code I am trying: date_default_timezone_set('America/New_York'); set_time_limit(0); ini_set("memory_limit", -1); $realPath = realpath( dirname(__FILE__) ); $path = $realPath.'/3pltracking/'; $files = scandir($path); $FilePath = $path.$files[2]; $result = array(); $date = date('m-d-Y_his'); if (file_exists($FilePath)) { if (($handle = fopen($FilePath, "r")) !== FALSE) { $i=0; while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) { $i++; if($i==1) continue; //$list = array('$data[2],$data[25],$data[4],$data[30],$data[41],$data[27]'); echo $data[2].",".$data[25].",".$data[4].",".$data[30].",".$data[41].",".$data[27]; echo "<br>"; $list = array($data[2].",".$data[25].",".$data[4].",".$data[30].",".$data[41].",".$data[27]); // the problem is here I believe as it is empty array if I check it outside while loop } fclose($handle); $headers = array('ReferenceNumber', 'TotalCartons', 'ShipCarrier', 'TrackingNum', 'FreightPP', 'TotalWeight'); $fp = fopen($realPath.'\3pltracking\TrackingFiles\Tracking_File_'.$date.'.csv', 'w'); fputcsv($fp, $headers); foreach ($list as $line) { $val = explode(",", $line); fputcsv($fp, $val); } fclose($fp); } else { $body = "File Not Found"; } } Here is my CSV file data: TransactionNumber,CustomerName,ReferenceNumber,PurchaseOrderNumber,ShipCarrier,ShipService,ShipBilling,ShipAccount,EarliestShipDate,CancelDate,Notes,ShipToName,ShipToCompany,ShipToAddress1,ShipToAddress2,ShipToCity,ShipToState,ShipToZip,ShipToCountry,ShipToPhone,ShipToFax,ShipToEmail,ShipToCustomerName,ShipToDeptNumber,ShipToVendorID,TotalCartons,TotalPallets,TotalWeight,TotalVolume,BOLNum,TrackingNum,TrailerNum,SealNum,ShipDate,ItemNumber,ItemQuantityOrdered,ItemQuantityShipped,ItemLength,ItemWidth,ItemHeight,ItemWeight,FreightPP,WarehouseID,LotNumber,SerialNumber,ExpirationDate,Supplier,Cost,FulfillInvShippingAndHandling,FulfillInvTax,FulfillInvDiscountCode,FulfillInvDiscountAmount,FulfillInvGiftMessage,SoldToName,SoldToCompany,SoldToAddress1,SoldToAddress2,SoldToCity,SoldToState,SoldToZip,SoldToCountry,SoldToPhone,SoldToFax,SoldToEmail,SoldToCustomerID,SoldToDeptNumber,FulfillInvSalePrice,FulfillInvDiscountPct,FulfillInvDiscountAmt 242328,PARADIGM TRENDS,123810,40-402849,CUSTOMER PICK UP,LTL,FreightCollect,,,,,HG BUYING- JEFFERSON DC 884,HG BUYING- JEFFERSON DC 884,125 LOGISTICS CENTER PKWY,,JEFFERSON,AL,30549,US,,,,,,,30,0,30,0.0174,,,,,,DOV3S,64,64,4,1,1,4,0,1,,,,,,0,0,,0,,,,,,,,,,,,,,,0,0,0 33,d,123810,40-402849,CUSTOMER PICK UP,LTL,FreightCollect,,,,,HG BUYING- JEFFERSON DC 884,HG BUYING- JEFFERSON DC 884,125 LOGISTICS CENTER PKWY,,JEFFERSON,AL,30549,US,,,,,,,30,0,30,0.0174,,,,,,DOV3S,64,64,4,1,1,4,0,1,,,,,,0,0,,0,,,,,,,,,,,,,,,0,0,0 44,PARAdgdfDIGM TRENDS,123810,40-402849,CUSTOMER PICK UP,LTL,FreightCollect,,,,,HG BUYING- JEFFERSON DC 884,HG BUYING- JEFFERSON DC 884,125 LOGISTICS CENTER PKWY,,JEFFERSON,AL,30549,US,,,,,,,30,0,30,0.0174,,,,,,DOV3S,64,64,4,1,1,4,0,1,,,,,,0,0,,0,,,,,,,,,,,,,,,0,0,0 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,BY3M,176,176,11,1,1,11,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0
There are so many ways of going about this... including str_getcsv($csvData). However here we'd go for something old-school & a bit twisted;-). We would create a Function that uses Regex and a Looping Construct to build-up the relevant CSV Data Structure. The Function below illustrates how. Also note that although we mentioned that this is a somewhat twisted, old-school approach: don't be fooled... because it does its thing still ;-). <?php $csvSourceFile = __DIR__ . "/1.csv"; $csvPreferredColumns = array('ReferenceNumber', 'TotalCartons', 'ShipCarrier', 'TrackingNum', 'FreightPP', 'TotalWeight'); $newCsvStrut = processCSVData($csvSourceFile, $csvPreferredColumns, __DIR__ . "/test.csv"); /** * #param $csvSource // PATH TO THE MAIN CSV FILE * #param array $csvPreferredColumns // ARRAY OF HEADER COLUMN-NAMES TO BE EXTRACTED FROM MAIN CSV * #param null $newCSVFileName // NAME OF THE NEW CSV FILE TO BE CREATED. * #return string */ function processCSVData($csvSource, array $csvPreferredColumns, $newCSVFileName=null){ // GET THE CONTENTS OF THE CSV FILE & STORE IT IN A VARIABLE $csvData = file_get_contents($csvSource); // SPLIT THE CONTENTS OF THE CSV FILE LINE BY LINE: THAT IS; AT THE END OF EACH LINE // THUS CONVERTING THE DATA TO AN ARRAY... $arrCsvLines = preg_split("#\n#", $csvData); //FILTER OUT UNWANTED EMPTY VALUES FROM THE ARRAY $arrCsvLines = array_filter($arrCsvLines); // CREATE SOME VARIABLES TO BE USED WITHIN THE LOOP... $strDataFinal = ""; $arrDataMain = $arrDataFinal = array(); // IF THERE IS MORE THAN ONE LINE IN THE ARRAY WE CREATED ABOVE, // THEN CONTINUE PROCESSING THE DATA... if($arrCsvLines && count($arrCsvLines)>0){ // SINCE THE HEADER IS ALWAYS THE FIRST LINE IN THE CHAIN, // WE EXPLICITLY EXTRACT IT AND STORE IT IN A VARIABLE FOR LATER USE $arrCsvHeaders = preg_split("#\,([\s\t]+)?#", $arrCsvLines[0]); // NOW WE LOOP THROUGH ALL THE LINES WE CREATED BY SPLITTING THE CONTENTS // OF THE CSV FILE AT THE END-OF-LINE BOUNDARY foreach($arrCsvLines as $key=>$arrCsvLine){ // WE DON'T WANT ANYTHING AT INDEX "0" SINCE IT IS THE HEADER // AND WE ALREADY DEALT WITH IT ABOVE.... // SO IF THE INDEX $key IS NOT 0, WE CAN CONTINUE PROCESSING if($key != 0){ $arrDataTemp = array(); $arrTempCsvData = preg_split("#\,([\s\t]+)?#", $arrCsvLine); foreach($arrTempCsvData as $iKey=>$sData){ $arrDataTemp[$arrCsvHeaders[$iKey]] = $sData; } $arrDataMain[] = $arrDataTemp; } } foreach($arrDataMain as $iKey=>$subData){ $arrTempFinal = array(); foreach($subData as $key=>$data){ if(in_array($key, $csvPreferredColumns)){ $arrTempFinal[$key] = $data; } } $arrDataFinal[] = implode(",\t", $arrTempFinal); } $arrDataFinal = array_merge( array(implode(",\t", $csvPreferredColumns)), $arrDataFinal); $strDataFinal = implode("\n", $arrDataFinal); if($newCSVFileName){ file_put_contents($newCSVFileName, $strDataFinal); } } return $strDataFinal; } var_dump($newCsvStrut); // PRODUCES SOMETHING SIMILAR TO THE LINES BELOW: string 'ReferenceNumber, TotalCartons, ShipCarrier, TrackingNum, FreightPP, TotalWeight 123810, CUSTOMER PICK UP, 30, 30, , 0 123810, CUSTOMER PICK UP, 30, 30, , 0 123810, CUSTOMER PICK UP, 30, 30, , 0 , , , , , ' (length=204)
create multiple directories using loop in php
I am taking data from text file( data is: daa1 daa2 daa3 on separate lines) then trying to make folders with exact name but only daa3 folders is created. Also when i use integer it creates all folders, same is the case with static string i.e "faraz". $file = __DIR__."/dataFile.txt"; $f = fopen($file, "r"); $line =0; while ( $line < 5 ) { $a = fgets($f, 100); $nl = mb_strtolower($line); $nl = "checkmeck/".$nl; $nl = $nl."faraz"; // it works for static value i.e for faraz //$nl = $nl.$a; // i want this to be the name of folder if (!file_exists($nl)) { mkdir($nl, 0777, true); } $line++; } kindly help
use feof function its much better to get file content also line by line Check this full code $file = __DIR__."/dataFile.txt"; $linecount = 0; $handle = fopen($file, "r"); $mainFolder = "checkmeck"; while(!feof($handle)) { $line = fgets($handle); $foldername = $mainFolder."/".trim($line); //$line is line name daa1,daa2,daa3 etc if (!file_exists($foldername)) { mkdir($foldername, 0777, true); } $linecount++; unset($line); } fclose($handle); output folders 1countfaraz 2countfaraz 3countfaraz
Not sure why you're having trouble with your code, but I find it to be more straightforward to use file_get_contents() instead of fopen() and fgets(): $file = __DIR__."/dataFile.txt"; $contents = file_get_contents($file); $lines = explode("\n", $contents); foreach ($lines as $line) { $nl = "checkmeck/". $line; if (!file_exists($nl)) { echo 'Creating file '. $nl . PHP_EOL; mkdir($nl, 0777, true); echo 'File '. $nl .' has been created'. PHP_EOL; } else { echo 'File '. $nl .' already exists'. PHP_EOL; } } The echo statements above are for debugging so that you can see what your code is doing. Once it is working correctly, you can remove them. So you get the entire file contents, split it (explode()) by the newline character (\n), and then loop through the lines in the file. If what you said is true, and the file looks like: daa1 daa2 daa3 ...then it should create the following folders: checkmeck/daa1 checkmeck/daa2 checkmeck/daa3