I have 4 text files in one folder and a pattern.txt
to compare these text files..In pattern.txt
i have
insert
update
delete
drop
I need to compare this text file with those four text files and if these patterns matches any line in that text files i have to write those lines in another log file...i had read those files using linq..i need to compare those files and write in a text file with line number..here is my code
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);
}
EDIT I have already used c# to compare two text files but i need this in 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;
There might be a simpler solution, but this is at least working if you really want to use 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);
}
Or if you want, you can combine that into one LINQ query (but thats not very readable i think):
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;
Since I'm a linq enthusiast, and will sometimes use a tool when it's inappropriate (I agree with @juharr about using grep or something similar for this situation) here is a possible version for you.
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);
}
Then you'd write the output of this function to a file.
using (StreamWriter sw = new StreamWriter("log.txt", true))
{
foreach (var log in CreateMatchesLog("pattern.txt", @"c:\test"))
{
sw.WriteLine(log);
}
}
I've set append to true
in the StreamWriter
, because I assume you don't want to lose the contents of the file each time you run the programme.
It looks pretty inefficient (not tested that aspect), but it uses linq and lambdas up the wazoo!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With