2010-01-19 32 views
4

日誌處理我知道這可能不是最高效的,但我想處理一些日誌與LINQ聲明。這裏是日誌的樣子:與LINQ

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 

現在我想篩選出任何不與記錄開始,並且由name列(JASON,DEVON,謝莉)組,然後CROSS JOIN它所以它看起來像這樣:

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  

這是可能在一個單一的LINQ語句做?

+0

執行等等等等列遵循相同的模式相關的記錄? – Daniel

+0

這是一個日誌文件,所以它是純文本,因此沒有真正的「模式」,你已經把它。 – skb

+0

當然,有可能在一個語句) - LukeH在一個單一的LINQ的聲明中寫道光線跟蹤:http://blogs.msdn.com/lukeh/archive/2007/10/01/taking-linq-to-objects-到極端-A-完全linqified-raytracer.aspx – jball

回答

0

這裏是我想出了:

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(); 
} 
2

您可以使用LINQ(這裏我使用的方法符號)獲得行的結果一氣呵成:

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())); 

輸出:

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 

我認爲這是難以轉置雖然沒有標準的Zip函數,但是行列。也許這對你來說足夠好了?如果沒有,那麼你可能會做的最後一位與一個輔助方法是在單獨的IEnumerables迭代。