bestimmte Zeile einer csv finden und löschen

ohoh ...

object(DateTime)#1 (3) { ["date"]=> string(26) "2024-07-27 06:29:04.807495" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" }
Warning: fopen(HK40Log.csv): failed to open stream: No such file or directory in C:\Web\Apache24\htdocs\csvlog\Test\del-test3.php on line 19

alue of type null in C:\Web\Apache24\htdocs\csvlog\Test\del-test3.php on line 57
Fehler beim Parsen von ""

usw .....
 
Zuletzt bearbeitet:
PS: Dieses Grafana funktioniert ja offenbar mit dem Format wie es ist. Daher könnte man das Vorgehen etwas ändern: Die aktuelle Zeile nicht mit fgetcsv beim Einlesen parsen sondern als String lesen und mit str_getcsv für die Zeitvergleiche parsen. Dann, nach dem Ausdünnen, den unveränderten String wieder in die neue Datei speichern.
 
PS: Dieses Grafana funktioniert ja offenbar mit dem Format wie es ist. Daher könnte man das Vorgehen etwas ändern: Die aktuelle Zeile nicht mit fgetcsv beim Einlesen parsen sondern als String lesen und mit str_getcsv für die Zeitvergleiche parsen. Dann, nach dem Ausdünnen, den unveränderten String wieder in die neue Datei speichern.

PHP:
fputs($file_to_write, implode(";", $line) . "\n");

scheint das Problem mit "" oder Sonderzeichen zu lösen. Das Ergebnis sieht jetzt passend aus. Ich werde weiter testen und Prüfen!

Danke

btw. was passiert wenn ich die ausgedünnte Liste nochmal durchlaufen lasse?
Getestet: Sollte auch passen!

Meine Endfassung mit der ich jetzt arbeiten werde. Danke


PHP:
<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);

ini_set('memory_limit', '1024M'); // or you could use 1G

// CSV auslesen---------------------------------------------------------------------------------------------------------------------
// Intervall zwischen den Zeiten wenn ausgedünnt wird in Minuten:
$intvBetween = 30;
// Intervall in die Vergangenheit wo ausgedünnt werden soll
// in Tagen:
$intvBefore = 90;

$csvFile = 'HK40Log.csv';
$destFile = 'HK40Log-filtered.csv';
$now = new DateTime();

var_dump($now);

$lastWritten = new DateTime();
$file_to_read = fopen($csvFile, 'r');
$file_to_write = fopen($destFile, 'w+');
$lineNr = 1;

while (!feof($file_to_read)) {
    echo "Zeile $lineNr<br>";
    $line = fgetcsv($file_to_read, 1000, ';');
    // Damit der folgende Code fehlerfrei funktioniert
    // muss die Zeile erfolgreich geparst sein:
    if ($line !== false) {
        // Um von der genauen Position von Datum und Zeit unabhängig zu sein,
        // benutzen wir eine Regex:
        preg_match('/\d\d\.\d\d\.\d{4} \d\d:\d\d:\d\d/', $line[0], $matches);
        // Den Fall abfangen, dass dieses Format nicht gefunden wurde:
        if (isset($matches[0])) {
            var_dump($matches);
            $currentTime = DateTime::createFromFormat('d.m.Y G:i:s', $matches[0]);
            $diffBefore = $currentTime->diff($now);
            //var_dump($diffBefore->days);
            if ($diffBefore->days > $intvBefore) {
                var_dump('Zeile ist &auml;lter als ' . $intvBefore . ' Tage');
                // Die Zeile ist älter als $intvBefore,
                // prüfen ob das Intervall zwischen zwei Ausgaben
                // schon abgelaufen ist:
                $diffBetween = $currentTime->diff($lastWritten);
                var_dump($diffBetween->days);
                if ($diffBetween->i + $diffBetween->h * 60 > $intvBetween) {
                    var_dump('aber im ' . $intvBetween . ' Min Abstand, ohne &Auml;nderung schreiben');
                    $lastWritten = DateTime::createFromFormat('d.m.Y G:i:s', $matches[0]);
                    
                    fputs($file_to_write, implode(";", $line) . "\n");
                }
            } else {
                var_dump('Zeile ist j&uuml;nger als ' . $intvBefore . ' Tage, ohne &Auml;nderung schreiben');
                // Die Zeile ist jünger als $intvBefore,
                // wir schreiben sie direkt in die Zieldatei:
                
                fputs($file_to_write, implode(";", $line) . "\n");
            }

        } else {
            echo 'Fehler beim Parsen von ' . $line[0];
        }
    }
    $lineNr++;
}
fclose($file_to_read);
fclose($file_to_write);

rename('C:/Web/Apache24/htdocs/csvlog/' . $csvFile, 'C:/Web/Apache24/htdocs/csvlog/HK40Log-old.csv');
rename('C:/Web/Apache24/htdocs/csvlog/' . $destFile, 'C:/Web/Apache24/htdocs/csvlog/' . $csvFile);
?>
 
Zuletzt bearbeitet:
Freut mich zu lesen, dass Du zum Ziel gekommen bist.
Inzwischen habe ich noch heraus gefunden, dass man DateTime-Objekte mit den normalen Vergleichs-Operatoren, < > etc., vergleichen kann, das macht das Skript noch ein wenig kompakter und besser lesbar:
Code:
<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);

ini_set('memory_limit', '1024M'); // or you could use 1G

// CSV auslesen---------------------------------------------------------------------------------------------------------------------
// Intervall zwischen den Zeiten wenn ausgedünnt wird in Minuten:
$intvBetween = 30;
// Intervall in die Vergangenheit wo ausgedünnt werden soll
// in Tagen:
$intvBefore = 90;

$csvFile = 'HK40Log.csv';
$destFile = 'HK40Log-filtered.csv';
$timeBefore = new DateTime("-$intvBefore days");
var_dump($timeBefore);
$file_to_read = fopen($csvFile, 'r');
$file_to_write = fopen($destFile, 'w+');
$lineNr = 1;
while (!feof($file_to_read)) {
    echo "Zeile $lineNr<br>";
    $line = fgets($file_to_read);
    $csvParsed = str_getcsv($line, ';');
    // Damit der folgende Code fehlerfrei funktioniert
    // muss die Zeile erfolgreich geparst sein und das erste
    // Element mit Datum und Uhrzeit vorhanden:
    if (isset($csvParsed[0])) {
        // Um von der genauen Position von Datum und Zeit unabhängig zu sein,
        // benutzen wir eine Regex:
        var_dump($csvParsed[0]);
        preg_match('/\d\d\.\d\d\.\d{4} \d\d:\d\d:\d\d/', $csvParsed[0], $matches);
        // Den Fall abfangen, dass dieses Format nicht gefunden wurde:
        if (isset($matches[0])) {
            // Zeit der aktuellen Zeile bereit stellen:
            $currentTime = DateTime::createFromFormat('d.m.Y G:i:s', $matches[0]);
            if ($currentTime < $timeBefore) {
                var_dump("line is older than $intvBefore days");
                // Die Zeile ist älter als $intvBefore,
                // prüfen ob das Intervall zwischen zwei Ausgaben
                // schon abgelaufen ist:
                if (!isset($nextToWrite)) {
                    $nextToWrite = DateTime::createFromFormat('d.m.Y G:i:s', $matches[0]);
                    $nextToWrite->modify("-$intvBetween minutes");
                }
                if ($currentTime < $nextToWrite) {
                    var_dump('$intvBetween minutes exeeded, write it');
                    fwrite($file_to_write, $line);
                    $nextToWrite->modify("-$intvBetween minutes");
                }
            } else {
                var_dump("line is younger than $intvBefore days, write uncond.");
                // Die Zeile ist jünger als $intvBefore,
                // wir schreiben sie direkt in die Zieldatei:
                fwrite($file_to_write, $line);
            }

        } else {
            echo 'Fehler beim Parsen von "' . $csvParsed[0] . '"<br>';
        }
    }
    $lineNr++;
}
fclose($file_to_read);
fclose($file_to_write);
 
Zurück