5

I want to read a text file line by line and edit a specific line. So, I have put the text file into a string variable like:

string textFile = File.ReadAllText(filename);

My text file is like:

Line A
Line B
Line C
Line abc
Line 1
Line 2
Line 3

I have a specific string (="abc"), which I want to search in this textFile. So, I am reading the lines until find the string and going to the third line ("Line 3" -> this line is always different) after that found string:

string line = "";
string stringToSearch = "abc";

using (StringReader reader = new StringReader(textFile))
{
    while ((line = reader.ReadLine()) != null)
    {
        if (line.Contains(stringToSearch))
        {
            line = reader.ReadLine();
            line = reader.ReadLine();
            line = reader.ReadLine();

            //line should be cleared and put another string to this line.
        }
    }
}

I want to clear the third read line and put another string to this line and save the whole string into textFile.

How can I do this?

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Giovanni19
  • 135
  • 1
  • 2
  • 7
  • This might help: [File.ReadAllLines](https://msdn.microsoft.com/en-us/library/system.io.file.readalllines(v=vs.110).aspx). Use this, loop through all lines, replace the one you want to replace, then just write back to the original file. – Tamás Szabó Aug 30 '17 at 10:37

4 Answers4

5

You can store the contents in a StringBuilder like this:

StringBuilder sbText = new StringBuilder();
using (var reader = new System.IO.StreamReader(textFile)) {
    while ((line = reader.ReadLine()) != null) {
        if (line.Contains(stringToSearch)) {
            //possibly better to do this in a loop
            sbText.AppendLine(reader.ReadLine());
            sbText.AppendLine(reader.ReadLine());

            sbText.AppendLine("Your Text");
            break;//I'm not really sure if you want to break out of the loop here...
        }else {
            sbText.AppendLine(line);
        }
    }
}  

and then write it back like this:

using(var writer = new System.IO.StreamWriter(@"link\to\your\file.txt")) {
    writer.Write(sbText.ToString());
}

Or if you simply want to store it in the string textFile you can do it like this:

textFile = sbText.ToString();
João Silva
  • 122
  • 10
waka
  • 3,362
  • 9
  • 35
  • 54
  • Thank you very much! This seems to be the right approach. Now, I have only the problem to have an error on writing the string back to the "textFile" string. "Illegal char in the path" for the following line: `using(var writer = new System.IO.StreamWriter(textFile)) {` – Giovanni19 Aug 30 '17 at 10:51
  • @Giovanni19: My mistake, "textFile" should be "Link to your text file you want to write to". I see that you used the variable differently in your post. If you simply want to store it as a string in `textFile` you can use: `textFile = sbText.ToString()`. I have updated the answer. – waka Aug 30 '17 at 10:53
  • Thanks. But this is adding the new line to the line which has e.g. the string "abc". I want to add the new line to the third line after the string "abc". – Giovanni19 Aug 30 '17 at 15:37
  • @Giovanni19: I have updated the answer. Now it should work like you wanted it to work. ;) – waka Aug 30 '17 at 16:14
2

Write the whole file again would be easier:

string old  = "abc";
string nw   = "aa";
int counter = 0;

using(StreamWriter w = new StreamWriter("newfile")
{
    foreach(string s in File.ReadLines(path))
        w.WriteLine(s == old ? nw : s);
}
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
Feras Al Sous
  • 1,073
  • 1
  • 12
  • 23
  • 1
    Now the line `abc` gets replaced, which is not what the OP wanted. Also `new` is a keyword and cannot be used as a variable name. – waka Aug 30 '17 at 10:39
  • Also, `using` must be lowercase, must have braces, and you can't do `if (foo = value)` because that won't evaluate to bool (and in some languages like C++ would change the value of `foo` and cause weird errors). You have to use `if (foo == value)` instead. Also, `nw` is a horrible variable name. Why not `newValue` or something descriptive? – AustinWBryan Jul 19 '18 at 17:52
2

You will probably want something like the following:

DirectoryInfo di = new DirectoryInfo(Location);
FileInfo[] rgFiles = di.GetFiles("txt File");

foreach (FileInfo fi in rgFiles)
{
    string[] alllines = File.ReadAllLines(fi.FullName);

    for (int i = 0; i < alllines.Length; i++)
    {
        if (alllines[i].Contains(stringToSearch))
        {                        
            alllines[i] = alllines[i].Replace(stringToSearch, some value );
        }
    }
}

This way you will be reading the text file line by line until the end of the document and if the value is picked up it will be replace by your new value.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
  • That's not what I want :/ See my first post. – Giovanni19 Aug 30 '17 at 15:56
  • @Giovanni19, You want to Read a document line by line and update a value (If it is found), you then want to update this value? I am right? This above code will work for that.... is it that you want to save a new version of this document? –  Aug 31 '17 at 07:45
2

Here is a full example:

using System;
using System.IO;

namespace rename
{
    class Program
    {
        static void Main(string[] args)
        {
            // Fix files, replace text
            DirectoryInfo di = new DirectoryInfo(@"C:\temp\all\");
            FileInfo[] rgFiles = di.GetFiles("*");

            foreach (FileInfo fi in rgFiles)
            {
                string[] alllines = File.ReadAllLines(fi.FullName);

                for (int i = 0; i < alllines.Length; i++)
                {
                    if (alllines[i].StartsWith("00:"))
                    {
                        // Edit: Replace these lines with an empty line
                        alllines[i] = alllines[i].Replace(alllines[i], "");
                    }
                }

                // Rewrite new files in the folder
                File.WriteAllLines(@"C:\temp\new\" + fi.Name, alllines);
            }
        }
    }
}
live-love
  • 48,840
  • 22
  • 240
  • 204