I have a large log file containing different record types that I want to parse. It looks something like this:
$L,8,PO
$L,8,SF
$P,8,P,0,102,0,19:08:34.463
$P,9,P,0,110,0,19:08:34.460
$P,8,P,0,105,0,19:08:34.407
$L,8,SF
$P,9,A,0,139,0,19:08:34.374
$P,15,P,0,103,0,19:08:34.532
$P,8,P,0,73,0,19:08:34.436
$L,8,SF
$L,8,PI
I'm currently using CsvHelper and followed this example of how to read multiple record types using a switch statement. I'm a bit stuck however, as I want to group the $P records depending on values contained in the $L records and then write the output to separate CSV files.
For example, the first and last $L records both contain an 8 in the second field, plus PO/PI messages (this would be the start/end of my file for all $P records containing 8 in the second field). The file output for 8.csv would look like this:
$P,8,P,0,102,0,19:08:34.463
$P,8,P,0,105,0,19:08:34.407
$P,8,P,0,73,0,19:08:34.436
In addition to grouping them together this way, I would like to prepend a number ahead of the $P record depending on the $L messages which contain SF and the number 8. There are 3 SF messages above containing SF and 8, so the final file would look something like this:
1,$P,8,P,0,102,0,19:08:34.463
1,$P,8,P,0,105,0,19:08:34.407
2,$P,8,P,0,73,0,19:08:34.436
What's the best way to accomplish this? Currently I'm adding all $P messages that contain the same ID number to a dictionary with key value pair of : List<$P Record>, and I'm not quite sure how to make the $P record groupings depend on the values of the other record.
Try something like this. It is easier to add lines to a record and then group the records.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication184
{
class Program
{
const string FILENAME = @"c:\temp\test.txt";
static void Main(string[] args)
{
int count = 0;
string line = "";
StreamReader reader = new StreamReader(FILENAME);
List<Record> records = new List<Record>();
while ((line = reader.ReadLine()) != null)
{
int startComment = line.IndexOf("//");
if (startComment >= 0)
{
line = line.Substring(0, startComment);
}
line = line.Trim();
string[] splitArray = line.Split(new char[] { ',' }).ToArray();
Record newRecord = new Record();
newRecord.car = int.Parse(splitArray[1]);
newRecord.type = (Record.RECORD_TYPE)Enum.Parse(typeof(Record.RECORD_TYPE), splitArray[2]);
records.Add(newRecord);
switch (splitArray[0])
{
case "$P":
newRecord.message = line;
break;
}
}
var cars = records.GroupBy(x => x.car);
foreach (var car in cars)
{
int lap = 0;
int stint = 0;
foreach (Record record in car)
{
record.lap = lap;
record.stint = stint;
switch (record.type)
{
case Record.RECORD_TYPE.SF:
record.lap = ++lap;
break;
case Record.RECORD_TYPE.P:
string output = string.Join(",", new string[] { record.stint.ToString(), record.lap.ToString(), record.message });
Console.WriteLine(output);
break;
case Record.RECORD_TYPE.PO :
record.stint = ++stint;
break;
}
}
}
Console.ReadLine();
}
}
public class Record
{
public enum RECORD_TYPE
{
PO,
SF,
P,
PI,
A
}
public RECORD_TYPE type { get; set; }
public int stint { get; set; }
public int lap { get; set; }
public int car { get; set; }
public string message { get; set; }
}
}