ManiacKnight
ManiacKnight

Reputation: 13

How do I delete all lines in text file below certain text?

I have a code which iterates through the entire text file searching for a specific text "[names]", and "tried" to delete all the lines below the text. I tried File.WriteAllText(INILoc, string.Empty);, but this just deletes everything in the entire text file. How do I make it so only all the lines below "[names]" gets deleted?

I have set up the iteration likes this :

string[] lines = File.ReadAllLines(INILoc);
bool containsSearchResul = false;
foreach (string line in lines)
    {
         if (containsSearchResul)
           {
                File.WriteAllText(INILoc, string.Empty);

           }
         if (line.Contains("[names]"))
           {
                containsSearchResul = true;
           }
    }

Upvotes: 1

Views: 573

Answers (5)

Ruviru
Ruviru

Reputation: 111

You can also use: WriteAllLines(string path, IEnumerable<string> contents) like this:

string[] lines = File.ReadAllLines(INILoc);
List<string> linesToWrite = new List<string>();

foreach(string line in lines)
{
    linesToWrite.Add(line);
    if (line.Contains("[names]")) break;
}

File.WriteAllLines(INILoc, linesToWrite);

Upvotes: 0

zhulien
zhulien

Reputation: 5715

Use StreamReader as it will give you the best performance as you don't need to read the whole file. Swap 'PATH TO INPUT FILE' with your file path and the result will be stored at the path you provide for 'PATH TO OUTPUT FILE'.

using (var sr = new StreamReader("PATH TO INPUT FILE"))
{
    using (var sw = new StreamWriter("PATH TO OUTPUT FILE"))
    {
        var line = sr.ReadLine();

        while (line != null)
        {
            sw.WriteLine(line);

            if (line.Contains("[names]"))
            {
                sw.Close();
                sr.Close();
            }
            else
            {                            
                line = sr.ReadLine();
            }                        
        }
    }
}

If you need to write to the same file:

var sb = new StringBuilder();

using (var sr = new StreamReader("PATH TO INPUT FILE"))
{
    var line = sr.ReadLine();

    while (line != null)
    {
        sb.AppendLine(line);

        if (line.Contains("[names]"))
        {
            sr.Close();
        }
        else
        {
            line = sr.ReadLine();
        }
    }
}

File.WriteAllText("PATH TO INPUT FILE", sb.ToString());

Upvotes: 1

Prasad Telkikar
Prasad Telkikar

Reputation: 16079

You need to store lines before "[names]" text into a string variable, and when condition (line.Contains("[names]")) satisfy then just break the loop and write string value into the same file.

Something like,

string[] lines = File.ReadAllLines(INILoc); //Considering INILoc is a string variable which contains file path.
StringBuilder newText = new StringBuilder();
bool containsSearchResul = false;

foreach (string line in lines)
    {
       newText.Append(line);
       newText.Append(Environment.NewLine); //This will add \n after each line so all lines will be well formatted

       //Adding line into newText before if condition check will add "name" into file
       if (line.Contains("[names]"))
              break;

    }

File.WriteAllText(INILoc, newText.ToString());
                        //^^^^^^^ due to string.Empty it was storing empty string into file.

Note: If you are using StringBuilder class, then do not miss to add Using System.Text in your program

Upvotes: 1

Chayim Friedman
Chayim Friedman

Reputation: 71330

The problem with your code is that it delete all the lines before the [names], not after (more exactly, write only the lines after that text). Also, any time you rewrite all the file content, and so remove all previous wrote line. It'll work as follows:

string[] lines = File.ReadAllLines(INILoc);
using (StreamWriter writer = new StreamWriter(INILoc)) // https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-write-text-to-a-file
{
            bool containsSearchResul = false;
            foreach (string line in lines)
            {

                if (!containsSearchResul)
                {
                    writer.Write(INILoc, string.Empty);

                }

                if (line.Contains("[names]"))
                {
                    containsSearchResul = true;
                }
            }
}

You have another, better option to do this with break:

string[] lines = File.ReadAllLines(INILoc);
using (StreamWriter writer = new StreamWriter(INILoc)) // https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-write-text-to-a-file
{
            foreach (string line in lines)
            {
                if (line.Contains("[names]"))
                {
                    break;
                }

                writer.WriteLine(INILoc, string.Empty);
            }
}

But you can do this in prefered, more-readable way, by using LINQ:

using System.Linq;

// ...

string[] lines = File.ReadAllLines(INILoc);
string[] linesTillNames = lines
                          .Take( // Take just N items from the array
                              Array.IndexOf(lines, "[names]") // Until the index of [names]
                          )
                          .ToArray();
File.WriteAllLines(INILoc, linesTillNames);

Upvotes: 0

Ricky Tucker Jr
Ricky Tucker Jr

Reputation: 36

Based on the requested code I have put together modifications.

    string[] lines = File.ReadAllLines(INILoc);
    //create a list to hold the lines
    List<string> output = new List<string>();
    //loop through each line
    foreach (string line in lines)
    {
        //add current line to  ouput.
        output.Add(line);
        //check to see if our line includes the searched text;
        if (line.Contains("[names]"))
        {
            //output to the file and then exit loop causing all lines below this 
            //one to be skipped
            File.WriteAllText(INILoc, output.ToArray());
            break;
        }
    }

Upvotes: 0

Related Questions