There is a file prepare_image.out which reflects the information of the form:

copy "..\какой-то путь\1.txt" to "..\путь\сюда" 1 File(s) copied copy "..\какой-то путь\2.txt" to "..\путь\сюда" 0 File(s) copied 

There are a lot of such lines and all reflect information about which file is being copied and information, whether the file was copied or not.
I implemented the search as follows:

 $temp = fopen("prepare_image.err", "a+"); $log = 'prepare_image.out'; $arr_log = file($log); $date = count($arr_log); $needle = '0 File(s) copied'; for ($i = 0; $i <= $date; $i++) { $read = $arr[$date - $i]; $pos = strripos($read, $needle); if ($pos === false) { echo "Ошибок, при копирование не обнаружено."; break; } else { echo "Warning! Обнаружены ошибки при копирование."; $string = substr($read, 0); fwrite($temp, $string ."\n"); } } 

Search is organized from the end of the file.
And here only the lines 0 File (s) copied fall into prepare_image.err, and you need to output the line OVER found 0 File (s) copied
That is, output $date - ($i+1) to another file
How can this be realized?

    2 answers 2

    Once, grep does not suit you, you cannot resist complicating your world. Regular expressions in this case, a bad idea, we are looking for a static string, which means we do not need them. If you do not need to process a huge file, use brute force. This problem can be solved in a hundred ways, but why?

     <?php $result = explode("\n", file_get_contents("result.log")); $errors = ""; foreach ($result as $key => $line) { if (trim($line) == '0 File(s) copied') $errors .= trim($result[$key - 1]) . PHP_EOL; } file_put_contents("result.err.log", $errors, FILE_APPEND); 
       grep -B1 '0 File(s) copied' prepare_image.out | grep copy > prepare_image.err 

      This is the most convenient way.

      grep is one of the most necessary tools for a programmer, a utility that serves precisely such purposes - searching in a file by pattern.

      the -B1 option tells the grepu to return one line before (Before) it found (just like A will add lines after)

      repeated grep launched through a pipeline operator (|) will return only lines with copy, without 0 File (s) copied. By the way, the pipeline operator wants to add to PHP.

      all output will be redirected to prepare_image.err

      If it is necessary on pkhp, then it is necessary to use preg_match_all ()

      • Is this command line utility for windows relevant? Maybe there is an alternative or do you have to do it through preg_match_all() ? - Yulenka
      • out of the box under Windows there is none, but finding and installing is not a problem. But I would recommend starting to master Linux - this system is much more convenient for the developer. - Ipatiev
      • but it is impossible to run FINDSTR again, similarly to your example with grep through a pipeline operator (|), isn't it? Just too, you can find the line: FINDSTR /C:"0 File(s) copied" prepare_image.out , but you can’t pick up the previous line, right? - Yulenka
      • It’s possible to start through the pipeline, but the previous FINDSTR lines do not seem to return - Ipatiev
      • Oh, I said that. It will give nothing. There is no parameter like -B1 = ( - Yulia