2

I'm a bit baffled by regex and I'm trying to get percentage progress from a line of a command line programme in PHP. A combination of problems.

I run a script from command line using exec

exec('python scriptos.py', $returnData, $returnCode);

Then I'm thinking to cycle through the returnData (which is changing live) - so I'm unsure how I can parse the response? I was going to foreach through $returnData - to find this...

[download]   1.0% of 218.08M at  431.42k/s ETA 08:32

Then I'm really struggling to work out the regex to get that percentage. My theory was to look for a number and ending percentage.

So, two way question

  1. How can I get access to this in PHP whilst the process is running?
  2. How do I get the data via regex preg_match?

Any help would be most helpful!

waxical
  • 3,826
  • 8
  • 45
  • 69

4 Answers4

3

You can often just use popen to read continuous output from a command:

$p = popen("sh -c 'while true ; do echo 99% ; sleep 0.5; done'", "r");
while (!feof($p)) {

    $line = fgets($p);
}

To get the percentage you need only a simple regex like:

preg_match('#([\d.]+)%#', $line, $match);
$percent = $match[1];
mario
  • 144,265
  • 20
  • 237
  • 291
3

to extract the progress from a line of output use this regex:

(\d+(\.\d+)?(?=%))

and to read the output use popen():

$handle = popen("yourCommand", "r");
while (!feof($handle)) {
    $data = fgets($handle);
    $matches = array();
    preg_match('/(?<percent>\d+(\.\d+)?(?=%))/', $data, $matches);
    echo $matches["percent"];
}
fardjad
  • 20,031
  • 6
  • 53
  • 68
  • This seems to be troublesome. It works, but it seems to end early. The command responds with the first 3 lines, but running at cmdline I get 5/6 lines response. Unfortunately, it's the 5/6 line I need. Is this somehow limited in time etc. I can't see as such on php man for popen. – waxical Dec 15 '11 at 09:30
  • FYI - this was fixed with the help of .... http://stackoverflow.com/questions/8523305/not-getting-entire-response-from-popen – waxical Dec 15 '11 at 16:40
  • @waxical I was scratching my head for a while and tried many things but couldn't reproduce the problem you had in first comment. Glad you figured it out. – fardjad Dec 15 '11 at 20:35
0
<?php

preg_match('#([0-9\.]+)%#', '[download]   1.0% of 218.08M at  431.42k/s ETA 08:32', $matches);

echo $matches[0]; # 1.0%

?>

Also check this out...

<?php

$string = '[download] 1.0% of 218.08M at 431.42k/s ETA 08:32';
$data = explode(' ', $string);

list( , $percentage, , $size, , $speed, , $eta) = $data;

echo $percentage, $size, $speed, $eta;

?>
Dejan Marjanović
  • 19,244
  • 7
  • 52
  • 66
0
$str = "[download]   99.55% adasdasd";
preg_match("/[0-9]{1,2}\.[0-9]{1,2}%/is", $str, $m);
print $m[0];
jmp
  • 2,456
  • 3
  • 30
  • 47
  • Including the `i` (case-insensitive) modifier is unnecessary here, because your regex has no letters in it. The `s` modifier is most likely also not necessary. – FtDRbwLXw6 Dec 14 '11 at 18:44