mpgn
mpgn

Reputation: 7251

read a file from a specific line php

I try to read some specific lines in text file.

My text file is like that :

#
#  Aliases in this file will NOT be expanded in the header from
#  Mail, but WILL be visible over networks or from /bin/mail.

# Basic system aliases -- these MUST be present.
mailer-daemon:  postmaster
postmaster:     root

# General redirections for pseudo accounts.
bin:            root
nscd:           root
pcap:           root
apache:         root
webalizer:      root

# boite fonctionnelles
# GEMEL
accueil:        demo1,demo2
services:       demo3,demo4
essai:          [email protected]

I want to collect this line for rework them after:

accueil:        demo1,demo2
services:       demo3,demo4
essai:          [email protected]

I can find this lines with the comment : # GEMEL

We can do this :

if($lines = file($filename)){

    foreach ($lines as $key => $value) {
        if(preg_match("/# GEMEL/", $value))
            for ($i=0; $i < ; $i++) { 
                # code...
            }


}

}

But it's not really good a double tab... The solution would be to move the pointer after find # GEMEL but how can i do that ?

Upvotes: 1

Views: 148

Answers (4)

Wiktor
Wiktor

Reputation: 3059

You can move to pointer of file stream with fseek() function.

Your function might look like that:

<?php
$f=fopen($file,'rb');
$pos = 0;
$blockSize = 8192;
while(!feof($f))
{
    if( $found = strpos( fread($f,$blockSize), '# GEMEL' ) )
    {
         $pos += $found;
         break;
    }
    else
    {
         $pos += $blockSize ;
    }
}
// now you can go to $pos
fseek( $f, $pos );
// read line you need
// ...


fclose($f);
?>

Upvotes: 0

RST
RST

Reputation: 3925

if($lines = file($filename)){
    foreach ($lines as $key => $value) {
        if(preg_match("/# GEMEL/", $value)) { 
            $myAccueil = $lines[$key+1];
            $myServices = $lines[$key+2];
            $myEssai = $lines[$key+3]; 
            break;       
        }
    }
} 

Upvotes: 0

mpyw
mpyw

Reputation: 5754

You don't have to use preg_match. I recommend you strpos.

<?php

$collection = '';
$count = 0;

$fp = fopen($filename,'rb') or die('Error');
while (($line = fgets($fp)) !== false) {
    if ($count === 0 && strpos($line, '# GAMEL') === 0) {
        $count++;
        continue;
    }
    if ($count >= 1 && $count <= 3) {
        $collection .= $line;
    }
    if ($count === 3)
        $count = 0;
}

echo $collection;

If you want $collection as an array,

<?php

$collection = array();
$count = 0;

$fp = fopen($filename,'rb') or die('Error');
while (($line = fgets($fp)) !== false) {
    if ($count === 0 && strpos($line, '# GAMEL') === 0) {
        $count++;
        continue;
    }
    if ($count >= 1 && $count <= 3) {
        $collection[] = rtrim($line);
    }
    if ($count === 3)
        $count = 0;
}

print_r($collection);

Upvotes: 0

shadyyx
shadyyx

Reputation: 16055

Just one dimensional loop:

$resultLines = array();
$save = false;

foreach ((array)file($filename) as $key => $value) {
    if (preg_match("/# GEMEL/", $value)) {
        $save = true;
        continue;
    }

    if ($save) {
        $resultLines[] = $value;
    }
}

var_dump($resultLines);

Requires that after the #GEMEL comment only a relevant lines exist. If that is not true, You could check for the next comment, and set the $save again to false.

Upvotes: 1

Related Questions