PHP to search within txt file and echo the whole line

205,024

Solution 1

And a PHP example, multiple matching lines will be displayed:

<?php
$file = 'somefile.txt';
$searchfor = 'name';

// the following line prevents the browser from parsing this as HTML.
header('Content-Type: text/plain');

// get the file contents, assuming the file to be readable (and exist)
$contents = file_get_contents($file);

// escape special characters in the query
$pattern = preg_quote($searchfor, '/');

// finalise the regular expression, matching the whole line
$pattern = "/^.*$pattern.*\$/m";

// search, and store all matching occurences in $matches
if (preg_match_all($pattern, $contents, $matches))
{
   echo "Found matches:\n";
   echo implode("\n", $matches[0]);
}
else
{
   echo "No matches found";
}

Solution 2

Do it like this. This approach lets you search a file of any size (big size won't crash the script) and will return ALL lines that match the string you want.

<?php
$searchthis = "mystring";
$matches = array();

$handle = @fopen("path/to/inputfile.txt", "r");
if ($handle)
{
    while (!feof($handle))
    {
        $buffer = fgets($handle);
        if(strpos($buffer, $searchthis) !== FALSE)
            $matches[] = $buffer;
    }
    fclose($handle);
}

//show results:
print_r($matches);
?>

Note the way strpos is used with !== operator.

Solution 3

Using file() and strpos():

<?php
// What to look for
$search = 'foo';
// Read from file
$lines = file('file.txt');
foreach($lines as $line)
{
  // Check if the line contains the string we're looking for, and print if it does
  if(strpos($line, $search) !== false)
    echo $line;
}

When tested on this file:

foozah
barzah
abczah

It outputs:

foozah


Update:
To show text if the text is not found, use something like this:

<?php
$search = 'foo';
$lines = file('file.txt');
// Store true when the text is found
$found = false;
foreach($lines as $line)
{
  if(strpos($line, $search) !== false)
  {
    $found = true;
    echo $line;
  }
}
// If the text was not found, show a message
if(!$found)
{
  echo 'No match found';
}

Here I'm using the $found variable to find out if a match was found.

Solution 4

$searchfor = $_GET['keyword'];
$file = 'users.txt';

$contents = file_get_contents($file);
$pattern = preg_quote($searchfor, '/');
$pattern = "/^.*$pattern.*\$/m";

if (preg_match_all($pattern, $contents, $matches)) {
    echo "Found matches:<br />";
    echo implode("<br />", $matches[0]);
} else {
    echo "No matches found";
    fclose ($file); 
}

Solution 5

looks like you're better off systeming out to system("grep \"$QUERY\"") since that script won't be particularly high performance either way. Otherwise http://php.net/manual/en/function.file.php shows you how to loop over lines and you can use http://php.net/manual/en/function.strstr.php for finding matches.

Share:
205,024
aullah
Author by

aullah

Updated on July 09, 2022

Comments

  • aullah
    aullah almost 2 years

    Using php, I'm trying to create a script which will search within a text file and grab that entire line and echo it.

    I have a text file (.txt) titled "numorder.txt" and within that text file, there are several lines of data, with new lines coming in every 5 minutes (using cron job). The data looks similar to:

    2 aullah1
    7 name
    12 username
    

    How would I go about creating a php script which will search for the data "aullah1" and then grab the entire line and echo it? (Once echoed, it should display "2 aullah1" (without quotations).

    If I didn't explain anything clearly and/or you'd like me to explain in more detail, please comment.

    • poke
      poke over 13 years
      “new lines coming in every 5 minutes” – That sounds like a lot of data. Maybe you should rethink whatever you are doing and use some database instead to store the values. Otherwise php will have big problems with the growing size of that file.
    • aullah
      aullah over 13 years
      Hey poke, thank you for your reply and concern. ;) The file won't really be too large, infact I think at the moment it's only approximately 150 lines. Although it does update every 5 minutes, it may only be 1 line or up to 20 lines at time. On certain occasions I may delete the lines in order to reset the data. The only reason I mentioned that the lines update, is so that when searching within the text file, I don't get an answer which is based upon lines. Again, I really do appreciate your response and thank you. ;)
    • Gordon
      Gordon about 13 years
      possible duplicate of PHP script to grab entire line
    • Faisal Shaikh
      Faisal Shaikh over 8 years
  • poke
    poke over 13 years
    Did you mean preg_match_all?
  • Lekensteyn
    Lekensteyn over 13 years
    Yes I did, I'm used to JS 'g' flag: using one function :o
  • aullah
    aullah over 13 years
    Hi Novikov, thank you for your response, I extremely appreciate it, as well as your efforts. I'll try and see if I can make heads and tails from the links you've provided. ;) The reason I can't use the system approach is that, I will eventually turn the script into a search. Of course, apologies that I didn't state this clearly. It's my fault. Sorry, and thank you for your response. ;)
  • aullah
    aullah over 13 years
    Hi Lekensteyn, I am extremely grateful of your response and fond of your coding. I'd love to use this script, however, every time I replace the text "name" within the $searchfor variable, I always get the error "No matches found". Of course, that's probably just me. There can be a lot of problems which cause this, and I'll try and find out whatever it is, but do you think it could be the coding? Again, apologies if I'm causing any hassle and I do extremely appreciate your response and efforts. Thank you. ;)
  • Jim
    Jim over 13 years
    The only beef I would have is suppressing the error. In my opinion, it is better to turn display_errors off when on production, but at least this way you see any errors and can fix them while under development. +1 for a good answer though.
  • aullah
    aullah over 13 years
    Hi Crayon Violent, thank you for your response. It is extremely appreciated, however, whenever I attempt to run this code, I always end up with a blank page within my browser. I'm currently running php 5.3.2, if that where the problem lies? Again, I appreciate your response and efforts. Thank you! ;)
  • aullah
    aullah over 13 years
    Hi shamittomar, thank you for your response. I extremely appreciate it and your coding! Thank you. ;) One thing though, I don't really like the idea of how the result is displayed within an array as I need the result to displayed to the end-user eventually. :( Of course, I do appreciate your response as well as your coding. Thank you. ;)
  • aullah
    aullah over 13 years
    Hi Frxstrem, thank you for your response. I'm extremely fond of it and I do appreciate your reply. The code seems to work fabulously, if possible do you think there is a possibility to add an "else" line against that "if". Something on the lines as "Not found"? Again, apologies if I'm asking for too much, just the way it is, is fine. I do appreciate your response and thank you very much! ;)
  • shamittomar
    shamittomar over 13 years
    @AUllah. You're welcome. I have just printed the array of result. It is upto you to show the array in any way you want. Do a foreach loop of the $matches and echo the results with your style and choice.
  • shamittomar
    shamittomar over 13 years
    @premiso, yes I agree with that practice completely. However, the if($handle) can have an else with stating that the file did not open correctly. I like this approach better. Just a matter of choice.
  • Jim
    Jim over 13 years
    Yea, the else would be good for user-friendly errors. But it is nice having the actual error too while you are developing.
  • jdonley
    jdonley over 13 years
    Could be any number of things, like wrong path/to/file, etc..can't really help w/out seeing what you actually did with it.. but something like this is really only good for short files. Overall as I mentioned it would be better to read it line by line, which shamittomar's answer details, so stick with that one.
  • Frxstrem
    Frxstrem over 13 years
    @AUllah1: It's pretty easy to do, so I have updated my answer with that
  • Lekensteyn
    Lekensteyn over 13 years
    Added m flag and changed implode("\n", $matches) to implode("\n", $matches[0]). Tested it, and it works now. Try it again :)
  • vp_arth
    vp_arth over 8 years
    Provide this something brand new for this 5yrs old question?
  • vp_arth
    vp_arth over 8 years
    /^.*$pattern.*\$/ expression is the same to just /$pattern/
  • Lekensteyn
    Lekensteyn over 8 years
    ^*. is not a valid regex... it is not an error so I have rolled back that change.
  • StanE
    StanE over 8 years
    If you are using fgets() without a length (second param), then your script still might stop due to memory limit. This is because fgets() reads a line. But if you have a binary file (or a text file which is just extremely long) then the function might read until the end of the file! It does not guarantee you to read the entire file. Just add a length, e. g. 262144 (256 KiB).
  • Elliot Robinson
    Elliot Robinson over 6 years
    You really don't want to pass anything to system(), shell_exec(), exec(), etc without using escapeshellarg() ... it often creates a big security issue :-)
  • Thomas Fellinger
    Thomas Fellinger over 5 years
    somehow it helps me now.
  • MaXi32
    MaXi32 over 3 years
    What about exact match? Let say I have 1.2.3.4 and 1.1.2.45 then searching 1.2.3.4 also will output 1.1.2.45