I need to read a CSV file that is not mine. So sometimes the delimiter will be a semicolon and an another time it will be a comma. So I need to find a way to know which one will be the right delimiter.
I use fgetcsv with a third parameter that is the delimiter.
My first option was to make a fgets and a strpos with semicolon and comma. But when I use fgets my cursor jump to the second line. And I need every line. So next to that I try to use rewind or fseek to go back to the beginning of my file. But the file is on read only mode and I can't rewind it.
My second option was to have 2 handles for only one file. I can't use this it take 2x more times. I want something clean and optimize.
How can i do that ?
Thanks.
Related
I have the following string in a text file:
<!--
///////////////////////////////////////////////////////////////////////////////////////
//
// Individuals
//
///////////////////////////////////////////////////////////////////////////////////////
-->
I need to write text two lines below the above part. There are many other sections like the one above, but each one doesn't repeat, so I know there is only one "Individuals".
I need to overwrite the file, so how can I set the position of my output to there?
There are two approaches:
Read the file line by line. Check each line if it matches to certain conditions. If yes, insert lines.
Read the full file, replace the text wanted and write the full file.
As long as your traffic is not too high, method 2 will be simpler. In order to replace the full block, I suggest this regex:
/(<!--[\s\r\n/]*Individuals[\s/]*)[^\s/]*([\s/]*-->)/
It matches the full block containing "Individuals" followed by some content on the new line. The block before the separate content is being caught by parenthesis, in order to do a replace:
$content = file_get_contents('myfile.txt');
$newContent = preg_replace("#(<!--[\s\r\n/]*Individuals[\s/]*)[^\s/]*([\s/]*-->)#", "$1$myNames$2", $content);
file_put_contents('myfile.txt', $newContent);
The preg_replace concatenates the first part of the block, some slashes and "Individuals", together with $myNames, and together with the closing part of the block to a new block.
I have not tested this finally in the shell, so I apologize for a possible typo. But I'm sure this will work out.
I have a text file of approximately 25,000 lines. About 525kb.
Some lines have random text at the beginning.
Some have long strings of semicolons.
Some others only have three semi-colons and then a space and optionally more text on the same line. These are the lines I want to remove.
Here is a sample....
;;; Updated Time 20120706122706
;;; Generic DEveloper Output
;;; Some Random Comments
;;; I got some more...
;;; Yet another uneeded line
;;; Thanks for using StackOverflow <http://stackoverflow.com>, or...
;;; Not.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Banana Production
[Data_Release_Version]
Version=12586
Released=20120706122706
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Baseline Properties
[BaseLineProperties]
Comment=BaselineProperties
----- and so on.
Once it gets to the first line with 4 or more ; on the line, I need the rest of the file as there are no ";;; " lines.
Trying to find something fast instead of reading everything line and writing it back out if it doesn't match ";;; ".
File is ASCII (possibly UTF-8) text type file.
Any ideas?
Thank you for your time, assistance and knowledge.
What I would suggest is to use file_get_contents() and save file's contents in a variable as a string, then use explode() that string at every newline character, then in a foreach loop, use preg_match() to check if the line begins with 3 semicolons and a space, if it dosent, put it in another array named $output. After foreach, implode() $output and add a newline character and use file_put_contents() to print it in another file. Hope this helps :-)
code:
<?php
$string = file_get_contents($filename);
$array = explode("\n",$string);
foreach($array as $arr) {
if(!(preg_match("^;;;\s",$arr))) {
$output[] = $arr;
}
}
$out = implode("\n",$output);
file_put_contents($path,$out);
?>
Depends.. I would try to load into a string, then do a explode() with newline, so it's in array, then run a foreach with a skip on any that doesnt have strpos == 0 -AND- strpos !== false, you can put in a continue to skip to the next line if it doesnt match.
Another option, is to parse, and skip, or even using fseek, and such. Depends on alot of different factors to determine whats going to be fastest.
You can implode later on, and add the newlines back in, and then push out a file, and/or use line breaks. Depending where the output is supposed to go.
I think you gave the answer yourself:
Make a script that reads the input file line by line in a loop (while). It writes every line into an output file if two conditions are met: 1. a flag ("done") is FALSE and 2. the line does NOT start with ";;; " (not the blank). This removes those lines starting with three semicolons. Once you come about a line containing more semicolons you set the flag to TRUE, thus the remaining lines wil be copied without being examined.
I have a .txt file with content(see first image) I need the content in such a way that It should be numbered and comma at the end of every line(see second image).
I want to insert say: "1"=>" in front of the first line. The numbering will increase on the second line so having about 4747 lines the last number will be 4747.
then insert: ", at the end of every line.
I have some knowlege in PHP so if somebody has solution or idea that will be helpful. I have been formatting this manually and that is very time consuming
Using PHP:
open your original file (consider fopen() or file_get_contents)
Split into an array by newline (explode())
process array line by line (for or foreach)
prepend the current line number
append quote and comma
loop to next array member
When finished - save content to file (file_put_contents())
That should be enough for you to work it out for yourself!
Use PHP's file(), which will give you an array with one element for each line. After that it should be a simple matter of iterating over the array with foreach and concatenating the appropriate bits onto the string. Then use fopen() and fwrite() to write the edited lines to your output file.
I use PHP to read lines by given offset (using fseek) as
fseek($fp, 51);
$data = fgets($fp, 4096);
The length of each line is less than 10 characters. Can I make a fixed length of 10 to have the start of each line as 0,10,20,30,40, ....
The lines are as
first
second
third
As a matter of fact, I want to virtually (fake indeed), tell fseek() that each line is 10 characters.
It sounds like you should use fgets. There's no way to emulate lines being 10 characters when they're not without reading data and then processing it (there's no way to seek without knowing where to seek).
You could just use fgets to look through the lines and then substr() them all to 10 charactes
If the reason you're wanting to do this is for performance reasons, you will probably need to store the data differently (or use indexing). To be able to seek to a specific entry you would need to be able to figure out which etnry to seek to. The easiest way to allow that would be via padding of lines. (If each line entry is 10 characters, then can just seek and trim based on 10*x)
I have a lot of data in a CSV file. I wrote some code to extract only column 1 and put it in a txt file:
fwrite($file2, $data[0].',');
Now, this created a TXT file with all values separated by a comma.
However, after the last value was read there was an extra comma
I don't need this, because when I used foreach($splitcontents as $x=> $y) using a comma delimiter, it reads a garbage value at the end because of the extra comma.
How do I remove or avoid the comma at the end?
Use fputcsv() instead of misreimplementing it.
Instead of assembling the CSV file yourself field-wise you could use fputcsv() which puts it into the right format:
while (...) {
fputcsv($file2, array($data[0], $data[1], $data[22]) );
The second parameter must be an array. If you really only want one column, then leave out the rest.
Also for reading the files back in, check out fgetcsv(). This might simplify your foreach + $splitstring approach.
One way to solve the problem is to use rtrim($data, ',') on the data you load from the second file before splitting it. This will remove the trailing comma.
If you want to fix the file itself, you can do this:
ftruncate($file2, ftell($file2)-1);
You have to do this just before you call fclose()