За последние 24 часа нас посетили 124945 программистов и 6586 роботов. Сейчас ищут 1694 программиста ...

Обработка txt файла

Тема в разделе "PHP для новичков", создана пользователем KOS9I4OK, 9 июн 2023.

  1. KOS9I4OK

    KOS9I4OK Новичок

    С нами с:
    9 апр 2023
    Сообщения:
    4
    Симпатии:
    0
    Добрый вечер уважаемые знатоки.
    помогите с кодом, имеется txt файл в него ссыпаться логи. как сделать выборку и поиск по значению я разобрался

    Код (Text):
    1. <?php
    2. $file = 'main.txt';
    3.  
    4. $need = '0000001A0BC1E3';
    5.  
    6. foreach (file($file, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES) as $line) {
    7.     if (preg_match("~{$need}.*~", $line, $string)) {
    8.         echo str_replace($need, "$need:", $string[0]);
    9.     }
    10. }
    11. ?>
    все выводится на сайт, но в этом текстовом файле есть информация до поискового значения, и как ее вывести не знаю. Может кто подскажет?
     
  2. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    947
    Симпатии:
    147
  3. KOS9I4OK

    KOS9I4OK Новичок

    С нами с:
    9 апр 2023
    Сообщения:
    4
    Симпатии:
    0
    Спасибо конечно, но думал мне подскажут с кодом.
     
  4. musicman3

    musicman3 Активный пользователь

    С нами с:
    30 июн 2019
    Сообщения:
    147
    Симпатии:
    12
    Адрес:
    Дыра на карте
    Если это подобие лога, где каждая запись это новая строка, то можно распарсить в массив и далее работать уже с массивом.
     
  5. KOS9I4OK

    KOS9I4OK Новичок

    С нами с:
    9 апр 2023
    Сообщения:
    4
    Симпатии:
    0
    Да это лог файл, каждая запись новая строка.
    Вот его содержимое
    Код (Text):
    1.  
    2. 137.34.14.1    Jun 09 19:39:56    1    user    err        2023-06-09T19:39:34.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - Unable to sync time with ntp server time.windows.com, timezone 28
    3. 137.34.14.1    Jun 09 19:39:56    1    user    info        2023-06-09T19:39:34.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - EVENT:000:RTSP client 185.111.219.4 incoming command GET_PARAMETER
    4. 137.34.14.1    Jun 09 19:40:01    1    user    info        2023-06-09T19:39:39.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - EVENT:000:Request: /cgi-bin/sip_cgi?action=regstatus, userLevel=2, ip=91.107.86.49
    5. 137.34.14.1    Jun 09 19:40:14    1    user    err        2023-06-09T19:39:51.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - Unable to sync time with ntp server time-nw.nist.gov, timezone 28
    6. 137.34.14.1    Jun 09 19:40:26    1    user    info        2023-06-09T19:40:03.000000+07:00 60.5.3.252 DKS20211_rev5.4.3.8.4_18688231BFF5 - - - EVENT:000:RTSP client 185.111.219.4 incoming command GET_PARAMETER
    Вот после искомого значения "185.111.219.4" я получаю текст, а вот до него нет. подскажите кодик? или строчку вывести со всем значением.
     
  6. Aleksandr.B

    Aleksandr.B Активный пользователь

    С нами с:
    2 фев 2023
    Сообщения:
    159
    Симпатии:
    41
    Адрес:
    Барнаул
    PHP:
    1. foreach (file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
    2.     if (stripos($line, $need) !== false) {
    3.         echo str_replace($need, "$need:", $line) . PHP_EOL;
    4.     }
    5. }
     
  7. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    947
    Симпатии:
    147
    Обожаю такие решения, особенно, когда файл с логом гигов 10 случайно оказывается ))
     
    MouseZver нравится это.
  8. Aleksandr.B

    Aleksandr.B Активный пользователь

    С нами с:
    2 фев 2023
    Сообщения:
    159
    Симпатии:
    41
    Адрес:
    Барнаул
    PHP:
    1. function read($path): Generator
    2. {
    3.     $handle = fopen($path, "r");
    4.  
    5.     while (!feof($handle)) {
    6.         yield fgets($handle);
    7.     }
    8.  
    9.     fclose($handle);
    10. }
    11.  
    12. $generator = read($file);
    13.  
    14. foreach ($generator as $line) {
    15.     if (stripos($line, $need) !== false) {
    16.         echo str_replace($need, "$need:", $line);
    17.     }
    18. }
     
  9. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.840
    Симпатии:
    1.338
    Адрес:
    Лень
    Все выше перечисленный код говно.
    Все ваши fopen, popen, file - канут на дно.
    Явись на свет о божественный и встроенный класс для всего этого...
    PHP:
    1. new SplFileObject( "Пук" )
     
  10. Aleksandr.B

    Aleksandr.B Активный пользователь

    С нами с:
    2 фев 2023
    Сообщения:
    159
    Симпатии:
    41
    Адрес:
    Барнаул
    Протестировал быстродействие чтения файла размером 12GB.
    При этом, если в данном файле делать поиск функцией stripos результата можно не дождаться.
    Изначально думал, что fopen будет быстрее, чем SplFileObject, но тесты показывают идентичный результат.

    fopen + yield: Time 12.416576147079 seconds. Memory 2.37 mb
    SplFileObject: Time 12.427870988846 seconds. Memory 2.37 mb
    SplFileObject + strpos: Time 30.803168058395 seconds. Memory 2.37 mb
    SplFileObject + stripos: Time 508.74000191689 seconds. Memory 3.32 mb
    Оптимальный результат.
    PHP:
    1. $file = new SplFileObject($file, 'r');
    2. while (!$file->eof()) {
    3.     $line = $file->fgets();
    4.     if (strpos($line, $need) !== false) {
    5.         echo str_replace($need, "$need:", $line);
    6.     }
    7. }
     
    #10 Aleksandr.B, 14 июн 2023
    Последнее редактирование: 14 июн 2023
  11. antoniii

    antoniii Активный пользователь

    С нами с:
    16 мар 2022
    Сообщения:
    419
    Симпатии:
    71
    Как прикольно считать PHP богом. Возможно, для некоторых это так и есть.
     
  12. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.840
    Симпатии:
    1.338
    Адрес:
    Лень
    показывай как ты тестировал.
     
  13. Aleksandr.B

    Aleksandr.B Активный пользователь

    С нами с:
    2 фев 2023
    Сообщения:
    159
    Симпатии:
    41
    Адрес:
    Барнаул
    В файле нет пустых строк и искомого значения "0000001A0BC1E3"
    PHP:
    1. <?php
    2.  
    3. $time_start = microtime(true);
    4.  
    5.  
    6. function formatBytes($bytes, $precision = 2)
    7. {
    8.     $units = array("b", "kb", "mb", "gb", "tb");
    9.  
    10.     $bytes = max($bytes, 0);
    11.     $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    12.     $pow = min($pow, count($units) - 1);
    13.  
    14.     $bytes /= (1 << (10 * $pow));
    15.  
    16.     return round($bytes, $precision) . " " . $units[$pow];
    17. }
    18.  
    19. $file = 'dev.log';
    20. $need = '0000001A0BC1E3';
    21.  
    22. //function read($path): Generator
    23. //{
    24. //    $handle = fopen($path, "r");
    25. //
    26. //    while (!feof($handle)) {
    27. //        yield fgets($handle);
    28. //    }
    29. //
    30. //    fclose($handle);
    31. //}
    32. //
    33. //$generator = read($file);
    34. //
    35. //foreach ($generator as $line) {
    36. //    if ($line === '') {
    37. //        echo $time_start . "\n";
    38. //    }
    39. //}
    40.  
    41.  
    42. $file = new SplFileObject($file, 'r');
    43.  
    44. //while (!$file->eof()) {
    45. //    $line = $file->fgets();
    46. //    if ($line === '') {
    47. //        echo $time_start . "\n";
    48. //    }
    49. //}
    50.  
    51. //while (!$file->eof()) {
    52. //    $line = $file->fgets();
    53. //    if (stripos($line, $need) !== false) {
    54. //        echo $time_start.'\n';
    55. //    }
    56. //}
    57.  
    58. while (!$file->eof()) {
    59.     $line = $file->fgets();
    60.     if (strpos($line, $need) !== false) {
    61.         echo $time_start.'\n';
    62.     }
    63. }
    64.  
    65.  
    66. $time_end = microtime(true);
    67. $time = $time_end - $time_start;
    68. echo "Time $time seconds.\n";
    69. echo "Memory " . formatBytes(memory_get_peak_usage());
     
    #13 Aleksandr.B, 15 июн 2023
    Последнее редактирование: 15 июн 2023
  14. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.840
    Симпатии:
    1.338
    Адрес:
    Лень
    PHP:
    1. $time_start = microtime(true);
    2.  
    3. // Time 16.979219913483 seconds.
    4. foreach ( new SplFileObject( '3g.bin', 'r' ) AS $id => $line )
    5. {
    6.    
    7. }
    8.  
    9.  
    10. // Time 17.596244096756 seconds.
    11. /* $handle = fopen('3g.bin', "r");
    12.  
    13. while (!feof($handle)) {
    14.     fgets($handle);
    15. }
    16.  
    17. fclose($handle); */
    18.  
    19.  
    20. $time_end = microtime(true);
    21. $time = $time_end - $time_start;
    22. echo "Time $time seconds.\n";
     
  15. Aleksandr.B

    Aleksandr.B Активный пользователь

    С нами с:
    2 фев 2023
    Сообщения:
    159
    Симпатии:
    41
    Адрес:
    Барнаул
    Делал тесты не один раз.
    С моим конфигом (php 7.4) время всегда разное, но плюс минут одинаковое.
    Иногда SplFileObject быстрее иногда fopen.
    Пробовал добавлять флаги для SplFileObject. Время практически не отличается.
    Возможно foreach немного быстрее.
     
    #15 Aleksandr.B, 15 июн 2023
    Последнее редактирование: 15 июн 2023
  16. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.840
    Симпатии:
    1.338
    Адрес:
    Лень
    каким циклов неважно. SplFileObject имеет все остальные функции по чтению больших файлов. То что выше написал - это результат только на 3 гигов данных и чем выше объем, тем существенно разница будет видна. По поводу цикла, я не вижу смысла дергать feof. И включать strpos у одной измеряемой функции, а в другой - игнорируя. Так что хз как у тебя там измеряется и при каких размерах файла.
     
  17. Aleksandr.B

    Aleksandr.B Активный пользователь

    С нами с:
    2 фев 2023
    Сообщения:
    159
    Симпатии:
    41
    Адрес:
    Барнаул
    Выше писал что тест проводил на логах в 12 GB. Четыре теста первые два на скорость чтения там нет strpos. 3 и 4 на поиск в строке. Да, можно и без feof SplFileObject наследуется от итератора. SplFileObject без feof не тестировал.
     
    #17 Aleksandr.B, 15 июн 2023
    Последнее редактирование: 15 июн 2023
  18. Aleksandr.B

    Aleksandr.B Активный пользователь

    С нами с:
    2 фев 2023
    Сообщения:
    159
    Симпатии:
    41
    Адрес:
    Барнаул
    Провел тесты еще раз. Чтобы не быть голословным


    SplFileObject + почти всегда быстрее
    SplFileObject + foreach всегда медленней чем while + eof и fopen + eof

    AMD Ryzen 5 3350G 16,0 ГБ samsung ssd 970 evo plus 250gb



    Результаты тестов:
    SplFileObject + eof
    Time 15.993134021759 seconds.
    Memory 2.35 mb

    Time 16.395498991013 seconds.
    Memory 2.35 mb

    Time 15.90164399147 seconds.
    Memory 2.35 mb

    =========================================
    SplFileObject без eof

    Time 18.657531023026 seconds.
    Memory 2.38 mb

    Time 17.759664058685 seconds.
    Memory 2.38 mb

    Time 18.000351905823 seconds.
    Memory 2.38 mb
    =======================================
    fopen + eof

    Time 16.367401123047 seconds.
    Memory 2.35 mb

    Time 16.460517883301 seconds.
    Memory 2.35 mb

    Time 16.38111114502 seconds.
    Memory 2.35 mb

    =====================================
    SplFileObject + setFlags +eof
    Time 16.057915210724 seconds.
    Memory 2.35 mb

    Time 16.160215139389 seconds.
    Memory 2.35 mb

    Time 15.913039922714 seconds.
    Memory 2.35 mb
     
    #18 Aleksandr.B, 16 июн 2023
    Последнее редактирование: 16 июн 2023
    don.bidon и musicman3 нравится это.
  19. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    947
    Симпатии:
    147
    Красава, тоже иногда бенчу от нечего делать, хотя самому и не надо, но интересно.