Log Processing Using LINQ

I know that this may not be the most productive, but I want to process some logs using the LINQ statement. This is what the magazine looks like:

RECORD DEVON 1 6748 bla bla bla bla bla bla bla bla bla bla bla bla RECORD JASON 1 7436 bla bla bla bla bla bla bla bla bla bla bla bla RECORD DEVON 2 9123 RECORD DEVON 3 3723 RECORD SHERRIE 1 6434 RECORD DEVON 4 3732 bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla RECORD SHERRIE 2 6434 bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla RECORD SHERRIE 3 9123 RECORD DEVON 5 3723 bla bla bla bla bla bla RECORD JASON 2 9123 RECORD DEVON 6 3723 bla bla bla bla bla bla bla bla bla bla bla bla RECORD JASON 3 9123 

Now I want to filter out everything that does not start with RECORD, and group it by the name column (JASON, DEVON, SHERRIE), and then cross-join it by name so that it looks like this:

 DEVON JASON SHERRIE 1/6748 1/7436 1/6434 2/9123 2/9123 2/6434 3/3723 3/9123 3/9123 4/3732 5/3723 6/3723 

Can this be done in a single LINQ statement?

+4
source share
2 answers

Here is what I came up with:

 public static string TransformLog(string fileName) { const string tab = "\t"; var fileLines = File.ReadAllLines(fileName); var testAreas = fileLines .Where(l => l.StartsWith("RECORD" + tab)) .Select(l => l.Split(tab.ToCharArray()).Skip(1).Take(3).ToArray()) .GroupBy(l => l[0]) .Select(g => new { g.Key, Enumerator = g.GetEnumerator() }) .ToList(); var sb = new StringBuilder(); testAreas.ForEach(ta => sb.Append(ta.Key + tab + tab)); sb.AppendLine(); bool cont; do { cont = false; testAreas.ForEach(ta => { var hasNext = ta.Enumerator.MoveNext(); sb.Append((hasNext ? ta.Enumerator.Current[1] + tab + ta.Enumerator.Current[2] + tab : tab + tab)); cont |= hasNext; }); sb.AppendLine(); } while (cont); return sb.ToString(); } 
0
source

You can get the results in rows at a time with Linq (here I use the method notation):

 string[] lines = File.ReadAllLines("input.txt"); var result = lines.Where(line => line.Substring(0, 6) == "RECORD") .Select(line => line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)) .GroupBy(columns => columns[1], columns => columns[2] + "/" + columns[3]) .Select(group => group.Key + " " + string.Join(", ", group.ToArray())); 

Output:

 DEVON 1/6748, 2/9123, 3/3723, 4/3732, 5/3723, 6/3723 JASON 1/7436, 2/9123, 3/9123 SHERRIE 1/6434, 2/6434, 3/9123 

It's hard for me to wrap rows in columns without the standard Zip function. Maybe this is good enough for you? If not, then you will probably have to make the last bit using a helper method that iterates over the individual IEnumerables.

+2
source

All Articles