C# search line and then overwrite it - c#

How can I find a line in C# and overwrite it (.sii file)?
string result = string.Empty;
var lines = File.ReadAllLines(Path);
foreach (var line in lines)
{
if (line.Contains("my_truck_placement: ("))
{
var text = line.Replace("my_truck_placement: ", "");
result = text.Trim();
File.WriteAllText(Path, result);
}
}

The main problem of yours is that you are trying to write to file too early, before you finish analyzing content of the file.
// use implicit types wherever possible
// Good to explicitly initiate with string.Empty :)
var result = string.Empty;
var lines = File.ReadAllLines(Path);
// I prefer here for each loop, as we are oging ot modify content of
// collection being iterated over.
for (var i = 0; i < lines.Length; i++)
{
var line = lines[i];
if (line.Contains("my_truck_placement: ("))
{
lines[i] = line.Replace("my_truck_placement: ", "");
}
}
// Here, after all manipulations, you are able to write to file.
File.WriteAllLines(Path, lines);
You could simplify even further, for example loop body:
lines[i] = lines[i].Replace("my_truck_placement: (", "(");
If you are sure the phrase will only happen at the beginning of the line.
You could even limit yourself to such code
File.WriteAllLines(
Path,
File.ReadAllLines(Path)
.Select(x => x.Replace("my_truck_placement: (", "("))
.ToArray());

Related

extracting a substring within a multiline string

I have a text file containing the following lines:
<TestInfo."Content">
{
<Label> "Content"
<Visible> "true"
"This is the text I want to get"
}
<TestInfo."Content2">
{
<Label> "Content2"
<Visible> "true"
"I don't want e.g. this"
}
I want to extract This is the text I want to get.
I tried e.g. the following:
string tmp = File.ReadAllText(textfile);
string result = Regex.Match(tmp, #"<Label> ""Content"" \n\s+ <Visible> ""true"" \n\s+ ""(.+?)""", RegexOptions.Singleline).Groups[1].Value;
However, in this case I get only the first word.
So, my output is: This
And I have no idea why...
I would appreciate any help. Thanks!
If you want the entire line after the line that starts with <Visible>, you'd better read the file line by line instead of using File.ReadAllText and a regular expression:
string result;
using (StreamReader sr = new StreamReader(textfile))
{
while (sr.Peek() >= 0)
{
string line = sr.ReadLine();
if (line.StartsWith("<Visible>"))
{
result = sr.ReadLine();
break;
}
}
}
Try this:
var tmp = File.ReadAllText("TextFile1.txt");
var result = Regex.Match(tmp, "This is the text I want to get", RegexOptions.Multiline);
if (result.Groups.Count> 0)
for (int i = 0; i < result.Groups.Count; i++)
Console.WriteLine(result.Groups[i].Value);
else
Console.WriteLine("string not found.");
Regards,
//jafc
You could change your regex this way:
var result = Regex.Match(tmp, #"<Visible> ""true""\s*""([\S ]+)""", RegexOptions.Singleline).Groups[1].Value;
If you want to get all the matches, not only the first one, you could use Regex.Matches
Thanks a lot for your input! This helped me to find a final solution:
First, I extracted only a small part containing the string I want to extract to avoid ambiguities:
string[] tmp = File.ReadAllLines(textfile);
List<string> Content = new List<string>();
bool dumpA = false;
Regex regBEGIN = new Regex(#"<TestInfo\.""Content"">");
Regex regEND = new Regex(#"<TestInfo\.""Content2"">");
foreach (string line in tmp)
{
if (dumpA)
Content.Add(line.Trim());
if (regBEGIN.IsMatch(line))
dumpA = true;
if (regEND.IsMatch(line)) break;
}
Then I can extract the (now only once existing) line starting with '"':
string result = "";
foreach (string line in Content)
{
if (line.StartsWith("\""))
{
result = line;
result = result.Replace("\"", "");
result = result.Trim();
}
}

How to add commas at the end of each line in a text file after using OpenFileDialog?

Ok so i am making a tool for a special need.
There will be .mif files which i can open as a text file and read the content.
Using something simple like
DialogResult openFile = form.openFileDialog1.ShowDialog();
if (openFile == DialogResult.OK)
{
int size = -1;
try
{
//Add commas here
}
catch (IOException)
{
}
}
Now how do i add a comma at the end of each line in a file?
e.g something like this
319621.99946835 110837.002493295
319640.501385461 110850.59860145
319695.199120806 110879.700271183
to something like this (notice the commas at the end of each line)
319621.99946835 110837.002493295,
319640.501385461 110850.59860145,
319695.199120806 110879.700271183,
Now the pattern is different for this and it occurs 1000s of time in one file
Any ideas?
string sFilePath = "Insert.File.Path.Here";
File.WriteAllLines(sFilePath, File.ReadAllLines(sFilePath).Select(x => string.Format("{0},",x)));
How to read a file line by line you will find in this post.
at each line do simply:
CurrentLine = CurrentLine + ",";
If your text file isn't big, you can try this:
var path = "myfile.txt";
var lines = File.ReadAllLines (path);
var newContent = string.Join (",\r\n", lines);
File.WriteAllText (path, newContent);
It will not add comma to last line.
Use the methods of the File class:
public static string[] ReadAllLines(
string path
)
public static void WriteAllLines(
string path,
string[] contents
)
Like this
string[] lines = File.ReadAllLines(openFile.FileName);
for (int i = 0; i < lines.Length; i++) {
lines[i] += ",";
}
File.WriteAllLines(openFile.FileName, lines);

C# - Writing a string next to a line or delete a string

I want to write a string next to a line, randomly could be any line, also I want to know how to delete a line from it, here is how my StreamReader works:
using (StreamReader sb = new StreamReader("admin.txt"))
{
string[] ffoo = File.ReadAllLines("admin.txt");
string[] ppoof = ffoo[0].Split(';');
string line;
while ((line = sb.ReadLine()) != null)
{
if (line.StartsWith("#" + Server.Name.ToLower() + ": "))
{
string[] punch = line.Split(';');
if (!punch.Contains(Channel.Name.ToLower()))
{
StringBuilder str = new StringBuilder("admin.txt");
str.Append(Channel.Name.ToLower() + ";");
return;
}
}
}
Here is how the list is made:
#main: alien;nobody;somebody;
#devs: headdev;wae;
It reads it fine just it can't write something next to main channel, I mean I can only write a line or a string next to end of it which is on dev, and I want to write something on main, also I have some problems on how to delete an admin from main or dev. also this file would be oversize, maybe includes 500 lines at all after we use it, so please if you can give a solution for big files, thanks!
When calling StringBuilder.Append it appends to the end of the string.
When calling the StringBuilder(string) constructor it will append to the string passed as parameter for the constructor.
In this case you are passing "Admin.txt" as a string, but you really want to pass the content of Admin.txt, so you need to read the content of it.
This should do the trick:
string[] lines = File.ReadAllLines("admin.txt");
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].StartsWith(string.Format("#{0}: ", Server.Name.ToLower()))
{
if (!lines[i].Split(';').Contains(Channel.Name.ToLower()))
lines[i] += ";" + Channel.Name.ToLower();
}
}
File.WriteAllLines("admin.txt", lines);
I'm sorry if I misunderstood what you wanted to do though.

Why is this code not replacing data in a text file?

I'm working on a small app which should read a file (ANSI 835) and replace data at certain positions with generic data. Basically I'm trying to scrub a person's first and last name from the file.
The line I'm searching for that contains the name looks like this:
NM1*QC*1*Doe*John*R***MI*010088307 01~
My code looks like this:
string[] input_file = (string[])(e.Data.GetData(DataFormats.FileDrop));
string output_file = #"c:\scrubbed.txt";
foreach (string file in input_file)
{
string[] lines = File.ReadAllLines(file);
foreach (string line in lines)
{
if (line.StartsWith("NM1*QC"))
{
line.Split('*')[1] = "Lastname";
line.Split('*')[2] = "Firstname";
}
}
File.WriteAllLines(output_file, lines);
}
The File.WriteAllLines works, but the data isn't being changed. I'm trying to get any line that starts with NM1*QC to look like this:
NM1*QC*1*Lastname*Firstname*R***MI*010088307 01~
There are many lines in the file that start with NM1*QC. What's the proper way to 'find and replace' and then create a new file in this situation?
As always, thanks for your time!
The calls to String.Split return variables that you neither capture, nor use, they do not change the underlying string. So your code equates to this:
if (line.StartsWith("NM1*QC"))
{
string[] split1 = line.Split('*')[1] = "Lastname";
string[] split2 = line.Split('*')[2] = "Firstname";
}
You would need to take the results of split1 and split2 and use those to recreate your string. Here is how I would re-write your code:
string[] input_file = (string[])(e.Data.GetData(DataFormats.FileDrop));
string output_file = #"c:\scrubbed.txt";
foreach (string file in input_file)
{
string[] lines = File.ReadAllLines(file);
for (int i=0; i < lines.length; i++)
{
string line = lines[i];
if (line.StartsWith("NM1*QC"))
{
string[] values = line.Split('*');
values[1] = "Lastname";
values[2] = "Firstname";
lines[i] = String.Join("*", values);
}
}
File.WriteAllLines(output_file, lines);
}
Notice I am recombining the individual values using the String.Join method, and inserting the new string back into the array of lines. That will then get written out as you expect.
Here you are creating a temporary array:
line.Split('*')
And you are changing its contents:
line.Split('*')[1] = "Lastname";
After the line has been executed the reference to this temporary array is lost and along with it go your changes.
In order to persist the changes you need to write directly to lines:
for (var i = 0; i < lines.Length; ++i)
{
var line = lines[i];
if (!line.StartsWith("NM1*QC"))
{
continue;
}
var parts = line.Split('*');
parts[3] = "Lastname";
parts[4] = "Firstname";
lines[i] = string.Join("*", parts);
}

Parsing individual lines in a robots.txt file with C#

Working on an application to parse robots.txt. I wrote myself a method that pulled the the file from a webserver, and threw the ouput into a textbox. I would like the output to display a single line of text for every line thats in the file, just as it would appear if you were looking at the robots.txt normally, however the ouput in my textbox is all of the lines of text without carriage returns or line breaks. So I thought I'd be crafty, make a string[] for all the lines, make a foreach loop and all would be well. Alas that did not work, so then I thought I would try System.Enviornment.Newline, still not working. Here's the code as it sounds now....how can I change this so I get all the individual lines of robots.txt as opposed to a bunch of text cobbled together?
public void getRobots()
{
WebClient wClient = new WebClient();
string url = String.Format("http://{0}/robots.txt", urlBox.Text);
try
{
Stream data = wClient.OpenRead(url);
StreamReader read = new StreamReader(data);
string[] lines = new string[] { read.ReadToEnd() };
foreach (string line in lines)
{
textBox1.AppendText(line + System.Environment.NewLine);
}
}
catch (WebException ex)
{
MessageBox.Show(ex.Message, null, MessageBoxButtons.OK);
}
}
You are reading the entire file into the first element of the lines array:
string[] lines = new string[] {read.ReadToEnd()};
So all your loop is doing is adding the whole contents of the file into the TextBox, followed by a newline character. Replace that line with these:
string content = read.ReadToEnd();
string[] lines = content.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
And see if that works.
Edit: an alternative and perhaps more efficient way, as per Fish's comment below about reading line by line—replace the code within the try block with this:
Stream data = wClient.OpenRead(url);
StreamReader read = new StreamReader(data);
while (read.Peek() >= 0)
{
textBox1.AppendText(read.ReadLine() + System.Environment.NewLine);
}
You need to make the textBox1 multiline. Then I think you can simply go
textBox1.Lines = lines;
but let me check that
Try
public void getRobots()
{
WebClient wClient = new WebClient();
string robotText;
string[] robotLines;
System.Text.StringBuilder robotStringBuilder;
robotText = wClient.DownloadString(String.Format("http://{0}/robots.txt", urlBox.Text));
robotLines = robotText.Split(Environment.NewLine);
robotStringBuilder = New StringBuilder();
foreach (string line in robotLines)
{
robotStringBuilder.Append(line);
robotStringBuilder.Append(Environment.NewLine);
}
textbox1.Text = robotStringBuilder.ToString();
}
Try using .Read() in a while loop instead of .ReadToEnd() - I think you're just getting the entire file as one line in your lines array. Debug and check the count of lines[] to verify this.
Edit: Here's a bit of sample code. Haven't tested it, but I think it should work OK;
Stream data = wClient.OpenRead(url);
StreamReader read = new StreamReader(data);
List<string> lines = new List<string>();
string nextLine = read.ReadLine();
while (nextLine != null)
{
lines.Add(nextLine);
nextLine = read.ReadLine();
}
textBox1.Lines = lines.ToArray();

Categories