2010-12-21 95 views
5

我有一個文件夾中的4個文本文件和pattern.txt把這些文本比較files..In pattern.txt我有使用linq比較兩個文本文件?

insert 
update 
delete 
drop 

我需要比較這四個文本文件,該文本文件,如果這些模式的任何行匹配在那個文本文件我必須在另一個日誌文件中寫這些行...我已經閱讀這些文件使用LINQ ..我需要比較這些文件,並在文本文件中寫入行號..這裏是我的代碼

var foldercontent = Directory.GetFiles(pathA) 
        .Select(filename => File.ReadAllText(filename)) 
        .Aggregate(new StringBuilder(), 
        (sb, s) => sb.Append(s).Append(Environment.NewLine), 
        sb => sb.ToString()); 

var pattern = File.ReadAllLines(pathB).Aggregate(new StringBuilder(), 
        (sb, s) => sb.Append(s).Append(Environment.NewLine), 
        sb => sb.ToString()); 

using (var dest = File.AppendText(Path.Combine(_logFolderPath, "log.txt"))) 
      { 
     //dest.WriteLine("LineNo : " + counter.ToString() + " : " + "" + line); 
      } 

編輯 我已經用C#來比較兩個文本文件,但我需要這在LINQ

while ((line = file.ReadLine()) != null) 
{ 
if (line.IndexOf(line2, StringComparison.CurrentCultureIgnoreCase) != -1) 
{ 
dest.WriteLine("LineNo : " + counter.ToString() + " : " + " " + line.TrimStart()); 
} 
counter++; 
} 
file.BaseStream.Seek(0, SeekOrigin.Begin); 
counter = 1; 
+0

你需要存儲匹配行來自哪個文件嗎? – 2010-12-21 12:58:56

+0

@Matt Ellen:我需要將匹配的行存儲在另一個文本文件中 – bala3569 2010-12-21 13:00:34

+0

@ bala3569:是的,但在日誌文件中,是否需要存儲匹配行來自哪個其他文件? – 2010-12-21 13:01:38

回答

4

有可能是一個簡單的解決方案,但至少這是工作,如果你真的想使用LINQ:

var foldercontent = Directory.GetFiles(pathA) 
        .Select(filename => new 
        { 
         Filename = filename, 
         Lines = File.ReadAllLines(filename) 
        }) 
        .SelectMany(file => file.Lines.Select((line, idx) => new 
        { 
         LineNumber = idx + 1, 
         Text = line, 
         FileName = file.Filename 
        })); 

var pattern = File.ReadAllLines(pathB); 

var result = from fileLine in foldercontent 
      where pattern.Any(p => fileLine.Text.IndexOf(p, StringComparison.CurrentCultureIgnoreCase) != -1) 
      select fileLine; 

foreach (var match in result) 
{ 
    System.Diagnostics.Debug.WriteLine("File: {0} LineNo: {1}: Text: {2}", match.FileName, match.LineNumber, match.Text); 
} 

或者,如果你願意,你可以是合併成一個LINQ查詢(但那不是很可讀,我認爲):

var result = from fileLine in (Directory.GetFiles(pathA) 
        .Select(filename => new 
        { 
         Filename = filename, 
         Lines = File.ReadAllLines(filename) 
        }) 
        .SelectMany(file => file.Lines.Select((line, idx) => new 
        { 
         LineNumber = idx + 1, 
         Text = line, 
         FileName = file.Filename 
        }))) 
       where File.ReadAllLines(pathB).Any(p => fileLine.Text.IndexOf(p, StringComparison.CurrentCultureIgnoreCase) != -1) 
       select fileLine; 
+0

如果我給它這意味着如果有n個匹配,它會寫n次var result1 = string.Join(「,」,result.Select(x => x.ToString())。ToArray()); foreach(var在結果中匹配) {dest.WriteLine(result1);} – bala3569 2010-12-21 14:49:38

+0

我不完全明白你的意思。我的LINQ查詢爲您提供所有文件的所有匹配行。你不會讓線加倍。 – Jan 2010-12-21 14:56:50

+0

亞,它給出正確,但寫n次n次匹配 – bala3569 2010-12-21 15:00:15

4

因爲我是一個LINQ愛好者,並且有時會使用工具時,它的inappropria te(我同意@juharr關於使用grep或類似的情況)這裏是一個可能的版本。

static IEnumerable<string> CreateMatchesLog(string patternFilePath, string pathToSearch) 
{ 
    string logTemplate = "File {0}, Line: {1}, Pattern: {2}"; 
    DirectoryInfo di = new DirectoryInfo(pathToSearch); 
    var patternlines = File.ReadAllLines(patternFilePath); 
    var fileslines = di.EnumerateFiles().Select(fi => File.ReadAllLines(fi.FullName).Select((line, i) => new {fi.FullName, line, i})); 

    return from filelines in fileslines 
      from pattern in patternlines 
      from fileline in filelines 
      where fileline.line.Contains(pattern) 
      select String.Format(logTemplate, fileline.FullName, fileline.i + 1, pattern); 
} 

然後,你會寫這個函數的輸出到一個文件。

using (StreamWriter sw = new StreamWriter("log.txt", true)) 
{ 
    foreach (var log in CreateMatchesLog("pattern.txt", @"c:\test")) 
    { 
     sw.WriteLine(log); 
    } 
} 

我追加設置trueStreamWriter,因爲我認爲你不希望在每次運行程序時就失去了文件的內容。

它看起來效率很低(沒有測試過這個方面),但它使用linq和lambda表示wazoo!