Robert Strauch
Robert Strauch

Reputation: 12896

Search and replace values in text file with C#

I have a text file with a certain format. First comes an identifier followed by three spaces and a colon. Then comes the value for this identifier.

ID1   :Value1  
ID2   :Value2  
ID3   :Value3

What I need to do is searching e.g. for ID2 : and replace Value2 with a new value NewValue2. What would be a way to do this? The files I need to parse won't get very large. The largest will be around 150 lines.

Upvotes: 2

Views: 22562

Answers (6)

mtijn
mtijn

Reputation: 3678

If the file isn't that big you can do a File.ReadAllLines to get a collection of all the lines and then replace the line you're looking for like this

using System.IO;
using System.Linq;
using System.Collections.Generic;

List<string> lines = new List<string>(File.ReadAllLines("file"));
int lineIndex = lines.FindIndex(line => line.StartsWith("ID2   :"));
if (lineIndex != -1)
{
    lines[lineIndex] = "ID2   :NewValue2";
    File.WriteAllLines("file", lines);
}

Upvotes: 4

Jason
Jason

Reputation: 3960

You can use regex and do it in 3 lines of code

string text = File.ReadAllText("sourcefile.txt");
text = Regex.Replace(text, @"(?i)(?<=^id2\s*?:\s*?)\w*?(?=\s*?$)", "NewValue2",
                     RegexOptions.Multiline);
File.WriteAllText("outputfile.txt", text);

In the regex, (?i)(?<=^id2\s*?:\s*?)\w*?(?=\s*?$) means, find anything that starts with id2 with any number of spaces before and after :, and replace the following string (any alpha numeric character, excluding punctuations) all the way 'till end of the line. If you want to include punctuations, then replace \w*? with .*?

Upvotes: 0

Dave R.
Dave R.

Reputation: 7304

Here's a simple solution which also creates a backup of the source file automatically.

The replacements are stored in a Dictionary object. They are keyed on the line's ID, e.g. 'ID2' and the value is the string replacement required. Just use Add() to add more as required.

StreamWriter writer = null;
Dictionary<string, string> replacements = new Dictionary<string, string>();
replacements.Add("ID2", "NewValue2");
// ... further replacement entries ...

using (writer = File.CreateText("output.txt"))
{
    foreach (string line in File.ReadLines("input.txt"))
    {
        bool replacementMade = false;
        foreach (var replacement in replacements)
        {
            if (line.StartsWith(replacement.Key))
            {
                writer.WriteLine(string.Format("{0}   :{1}",
                    replacement.Key, replacement.Value));
                replacementMade = true;
                break;
            }
        }
        if (!replacementMade)
        {
            writer.WriteLine(line);
        }
    }
}

File.Replace("output.txt", "input.txt", "input.bak");

You'll just have to replace input.txt, output.txt and input.bak with the paths to your source, destination and backup files.

Upvotes: 4

Steven Doggart
Steven Doggart

Reputation: 43743

Something like this should work. It's very simple, not the most efficient thing, but for small files, it would be just fine:

private void setValue(string filePath, string key, string value)
{
    string[] lines= File.ReadAllLines(filePath);
    for(int x = 0; x < lines.Length; x++)
    {
        string[] fields = lines[x].Split(':');
        if (fields[0].TrimEnd() == key)
        {
            lines[x] = fields[0] + ':' + value;
            File.WriteAllLines(lines);
            break;
        }
    }
}

Upvotes: 0

J0HN
J0HN

Reputation: 26941

You can use regexes to achieve this.

Regex re = new Regex(@"^ID\d+   :Value(\d+)\s*$", RegexOptions.IgnoreCase | RegexOptions.Compiled);

List<string> lines = File.ReadAllLines("mytextfile");
foreach (string line in lines) {
    string replaced = re.Replace(target, processMatch);
    //Now do what you going to do with the value
}

string processMatch(Match m)
{
    var number = m.Groups[1];
    return String.Format("ID{0}   :NewValue{0}", number);
}

Upvotes: -1

David W
David W

Reputation: 10184

Ordinarily, for any text searching and replacement, I'd suggest some sort of regular expression work, but if this is all you're doing, that's really overkill.

I would just open the original file and a temporary file; read the original a line at a time, and just check each line for "ID2 :"; if you find it, write your replacement string to the temporary file, otherwise, just write what you read. When you've run out of source, close both, delete the original, and rename the temporary file to that of the original.

Upvotes: 1

Related Questions