AShah
AShah

Reputation: 942

Parse file by finding one line in string plus the next line

I have the below output from an application and trying to parse it using c# asp.net

Output is in the link:

------------+-------------------------
ID          |3013940039
Session Name|SID-0000000058901C19-440
IP Address  |10.10.0.10 (DHCP)
Created at  |2017-12-03 09:37:37
Updated at  |2017-12-03 10:24:34
Location    |On 'Agmvpn01'
------------+-------------------------
ID          |3440042004
Session Name|SID-0000000061A459D0-443
IP Address  |10.10.0.12 (DHCP)
Created at  |2017-12-03 09:39:11
Updated at  |2017-12-03 10:24:35
Location    |On 'Agmvpn01'
------------+-------------------------
ID          |498444455
Session Name|SID-000000009EA543D1-442
IP Address  |10.10.0.13 (DHCP)
Created at  |2017-12-03 09:48:37
Updated at  |2017-12-03 10:24:35
Location    |On 'Agmvpn01'
------------+-------------------------
ID          |1631934168
Session Name|SID-000000002C393E76-432
IP Address  |10.10.0.14 (DHCP)
Created at  |2017-12-03 09:34:44
Updated at  |2017-12-03 10:24:35
Location    |On 'Agmvpn01'
------------+-------------------------
ID          |3771126469
Session Name|SID-0000000061A459D0-443
IP Address  |169.254.234.70
Created at  |2017-12-03 06:39:05
Updated at  |2017-12-03 06:39:09
Location    |On 'Agmvpn01'

I want to find the IP Address the DHCP allocated one plus the next line "Created at"

so in the end I would like to end up with

IP Address  |10.10.0.10 (DHCP)
Created at  |2017-12-03 09:37:37

Currently im using the below to get the IP address but Im also now after the next line

 List<string> foundDevicesIP = lines.ToList().Where(x =>
                    x.Contains("DHCP")).ToList();
 //sometimes DHCP flag is missing might need to grep for something else

 for (int i = 0; i < foundDevicesIP.Count; i = i + 1)
 {
     string[] ip2 = foundDevicesIP[i].Split('|');
     string[] finalIP = ip2[1].Split('(');
     lstAirMasjidFound.Items.Add(finalIP[0].TrimEnd());
 }

Upvotes: 1

Views: 61

Answers (1)

rene
rene

Reputation: 42444

If you want to do that with a LINQ query you can do so in two steps, first to get a collection for the lines that belong to each other. In your example that is indicated by the "--------+--------" lines. I use a runningSection variable fro that. In that same query we select the lines we're interested in. In your case DHCP and Created at.
From that we can do a group by to only select the groups that have at least two results. What is left is a simple selection of the correct line into the appropriate field.

This what your code will look like:

var runningsection = 0;
const string dhcp = "(DHCP)";
var foundDevicesIP = from l in lines
    let section = l.StartsWith("----") ? 
                  runningsection++:
                  runningsection                             // grouping for sections
    where l.StartsWith("Created at") || l.Contains(dhcp)     // which lines to keep
    group new {                                              // type with line and linetype properties
        line =  l.Split('|')[1].Replace(dhcp,String.Empty),  // parse/shape the value
        linetype = l.Contains(dhcp)?1:2                      // was it an IP address (1) or Created at (2)
    } by section into agg                                    // group the lines beloning to the same section
    where agg.Count() > 1                                    // which groups have 2 or more lines
    select new
        {   
            IP = agg.First( l => l.linetype == 1).line,      // the first object with linetype 1 is the IP
            Created = agg.First( l => l.linetype == 2).line  // the first object with linetype 2 is the creation date
        };


    var list = new List<string>();
    foreach(var deviceIP in foundDevicesIP) 
    {
        list.Add(String.Format("IP: {0} , # {1} #", deviceIP.IP, deviceIP.Created));
    }

When run with your example input this will be in the list:

list of IP and created

Upvotes: 1

Related Questions