I have a bunch of Powershell scripts which are executed and the full transcript is saved in a .log
file in a specific location. I can read the .log
file using:
string[] text = System.IO.File.ReadAllLines(@"D:\install.log");
foreach (string line in text)
{
Console.WriteLine(line);
}
In this .log
file, there is a lot of text and what I am trying to do is read specific sections of the .log
file and do operations based on those. So for example the .log
file contains something like this:
Executing script no. 1
#####LOTS OF POWERSHELL OUTPUT LINES HERE#####
Executing script no. 2
#####LOTS OF POWERSHELL OUTPUT LINES HERE#####
What I want to be able to do is read the text from Executing script no. 1
and up until Executing script no. 2
and then do some operations accordingly. And then move on to script no. 2
and then so on.
Also, something to note here is that the .log
file is being updated as the Powershell scripts are being executed. So when I start reading the .log
file, it continues being updated until all the scripts have been executed and I see: Transcript ended
at the end of the .log
file.
How can I read the .log
file in sections here?
CodePudding user response:
You can approach your problem with this pattern
List<string> section = new List<string>();
foreach (string line in System.IO.File.ReadLines(@"D:\install.log"))
{
if (line.StartsWith("Executing script no"))
{
ProcessSection(section);
section = new List<string>();
}
section.Add(line);
}
// Process the last section....
ProcessSection(section);
First, do not load all lines together in memory but read one by one accumulating them in a List of strings that represents the content of a section. Then when you find the line that start the section pass everything to your processing code and restart with a new section data
void ProcessSection(List<string> sectionData)
{
if(sectionData.Count == 0)
return;
// now you can loop over the strings in sectionData or
// rejoin everything with
// string.Join(Environment.NewLine,sectionData);
}
But, from your comment below, it seems that another process is writing to the file while you try to read it. In this context, File.ReadLines could fail because it will try to lock the file making impossible to the other process the write operation. (Or failing itself because it cannot lock the file).
In this context your need to read line by line in a different way
using (var fs = new FileStream("D:\\install.log", FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 0x1000, FileOptions.SequentialScan))
using (var sr = new StreamReader(fs, Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
{
// as above
}
}
CodePudding user response:
you can use the IndexOf() fucntion to get the starting point of your scripts and extract the part from inbetween
string[] text = System.IO.File.ReadAllLines(@"D:\install.log");
int start = text.IndexOf("Executing script no. 1")
int end = text.IndexOf("Executing script no. 2")
string scriptOneOutput = text.Substring(start , end-start);
//now scriptOneOutput should only contain the output from script one and you can process it