PHP count line/row on text file based on value column

前端 未结 2 1152
慢半拍i
慢半拍i 2021-01-26 05:02

Continuing on my previous question.

I have text log file called reject. You can see it here

As you can see there are 4 steps on tab called:

1. Ba         


        
相关标签:
2条回答
  • 2021-01-26 05:36

    if you're ok with writing down your columns as keys then this should work as you described:

    $fromDateTime = new DateTime('Wed, Sep 19  2018 08:00:00');
    $toDateTime = new DateTime('Wed, Sep 19  2018 19:59:00');
    $file = file_get_contents('Reject.txt');
    $lines = explode("\n", $file);
    
    // counter
    $rowsintimespan = 0;
    // keys should correspond to columns
    $keys = [
        'date',
        'time',
        'battery',
        'piezo',
        'leftD3',
        'rightD2'
    ];
    
    $values = array_fill(0, count($keys), 0);
    $values = array_combine($keys, $values);
    
    // Do Line-By-Line starting by Line 16 (Array Index 15)
    for ($i = 11; $i < count($lines); $i++) {
        // if the file is "Tue, Sep 18<tab>2018<tab>23:59:53<tab>"
        $dateobj = DateTime::createFromFormat("???,?M?d??Y?H:i:s+", $lines[$i]);
    
        // check if date is in your Timespan
        if ($dateobj < $toDateTime && $dateobj > $fromDateTime) {
            $rowsintimespan++; // count if in timespan
    
            // get line elements
            $lineContent = explode("\t", $lines[$i]);
    
            // loop through line elements and count them
            $x = 0;
            for ($j = 0; $j < count($keys); $j++) {
                if (!isset($lineContent[$j])) {
                    continue;
                }
    
                // remember position of last not empty column
                if (trim($lineContent[$j]) != '') {
                    $x = $j;
                }
            }
    
            if ($x > 0) {
                $values[$keys[$x]]++;
            }
        }
    }
    
    // Debug-Output
    echo $rowsintimespan;
    
    // Output every column
    echo '<pre>';
    print_r($values);
    

    This will print out:

    Array
    (
        [date] => 0
        [time] => 0
        [battery] => 4
        [piezo] => 31
        [leftD3] => 17
        [rightD2] => 1
    )
    
    0 讨论(0)
  • 2021-01-26 05:39

    Just split your row by your tabs and check for !empty();

    //Set Time-Span
    $fromDateTime = new DateTime('Wed, Sep 19  2018 00:00:00');
    $toDateTime = new DateTime('Wed, Sep 19  2018 17:00:00');
    
    // Load File
    $file = file_get_contents('Reject.txt');
    
    // Split by lines
    $lines = explode("\n",$file);
    
    // counter
    $rowsintimespan = 0;
    $rowswithbattery = 0;
    
    // Do Line-By-Line starting by Line 16 (Array Index 15)
    for($i = 15; $i < count($lines); $i++) {
        // if the file is "Tue,<space>Sep<space>18<space><space>2018<tab>23:59:53<tab>"
        $dateobj = DateTime::createFromFormat("???, M  d?Y?H:i:s+", $lines[$i]);
    
        // check if date is in your Timespan
        if($dateobj < $toDateTime && $dateobj > $fromDateTime) {
            $rowsintimespan++; // count if in timespan
            $cols = explode("\t",$lines[$i]);
            // 0 = Date, 1 = Time, 2 = Battery Level, 3 = Piezo, 4 = left, 5 = Right
            // Count Battery-Values
            if (!empty($cols[2])) {
                $rowswithbattery++;
            }
        }
    }
    
    // Debug-Output
    echo 'In Timespan: '.$rowsintimespan."\n";
    echo 'Rows With Battery: '.$rowswithbattery
    

    Produces:

    In Timespan: 84
    Rows With Battery: 84
    

    Full Example with all your columns: https://ideone.com/VAQH7h

    Also you could iterate over every header and create a neat array as I showed in https://ideone.com/YUU1jP

    // Split by lines
    $lines = explode("\n", $file);
    $header = explode("\t", $lines[9]);
    // counter
    $rowsintimespan = 0;
    $counter = Array();
    
    // Create an entry for every header and trim it to lose additional whitespaces
    foreach($header as $index => $head){
        $counter[rtrim($head)] = 0;
    }
    
    // Do Line-By-Line starting by Line 16 (Array Index 15)
    for($i = 11; $i < count($lines); $i++) {
        // the file is "Tue,<space>Sep<space>18<space><space>2018<tab>23:59:53<tab>"
        $dateobj = DateTime::createFromFormat("???, M d  Y?H:i:s+", $lines[$i]);
        // check if date is in your Timespan
        if($dateobj < $toDateTime && $dateobj > $fromDateTime) {
            $rowsintimespan++; // count if in timespan
            $cols = explode("\t",$lines[$i]);
            // 0 = Date, 1 = Time, 2 = Battery Level, 3 = Piezo, 4 = left, 5 = Right
            // Count Battery-Values
            foreach($header as $index => $head){
                // For every header check if col is empty
                $counter[rtrim($head)] += empty($cols[$index]) ? 0 : 1;
            }
        }
    }
    
    // Debug-Output
    echo 'In Timespan: '.$rowsintimespan."\n";
    var_dump($counter);
    

    Update to match the updated question:

    Then just do some simple math.

    Theory: if you have 80 set columns with battery, and 20 with set piezo, you can substract the 20 piezo counter from your 80 battery counter and then you know how many last battery-columns you have and how many last piezo columns.

    Thus:

    $lastwithright = $rowswithright;
    $lastwithleft = $rowswithleft - $rowswithright;
    $lastwithpiezo = $rowswithpiezo - $rowswithleft;
    $lastwithbattery = $rowswithbattery - $rowswithpiezo;
    
    0 讨论(0)
提交回复
热议问题