Replacing content in file

So, i have this file:

a b c aaaa ee

and i want to replace aaaa with d; and ee with e.

How do i do that?

A really weird idea came to me: i can divide this string using loops to something like that:

"a b c", "aaaa", "ee"

And then create new string and push content from array to it and if there is matched word replace it.

(still looking for more elegant and fast solutions)

If you're not particularly worried about allocation costs, the following is good enough:

use std::fs;

fn main() {
    //let data = fs::read_to_string("myfile.txt").unwrap(); // read from file into a string
    let data = String::from("a b c aaaa ee"); // using a hard coded string
    let new = data.replace("aaaa", "d").replace("ee", "e");
    dbg!(&data, &new);
}

Playground
This will return a new string which has replaced all occurences of "aaaa" or "ee".


To mutate the string, you could do

use std::fs;

fn main() {
    //let data = fs::read_to_string("myfile.txt").unwrap(); // read from file into a string
    let mut data = String::from("a b c aaaa ee"); // using a hard coded string
    
    let rules = &[("aaaa", "d"), ("ee", "e")];
    for (from, to) in rules {
        let start = data.find(from).unwrap();
        let range = start..start + from.len();
        data.replace_range(range, to);
    }
    dbg!(&data);
}
1 Like

Thanks for solution, i've already came up to it, but i need to change file.

Then you can just write back the mutated string into the file using File and its io::Write impl.

After reading the file, open it with truncate enabled to replace contents:

use std::fs::{self, OpenOptions};
use std::io::{self, prelude::*};

fn main() -> Result<(), io::Error> {
    let contents = fs::read_to_string("text.txt")?;
    let new = contents.replace("aaaa", "d").replace("ee", "e");
    dbg!(&contents, &new);

    let mut file = OpenOptions::new().write(true).truncate(true).open("text.txt")?;
    file.write(new.as_bytes())?;

    Ok(())
}
1 Like

You can't do these kind of mutations directly on a file. It's trivial to seek to an offset and replace the byte(s) there, but if you need to replace 'aaaa' with something shorter or longer like 'd' you also need to shift the bytes after it. Operating systems offer no API for this, so you need to do it manually, easiest is to read the entire file into memory and write it out after manipulation.

Or if atomicity (that another program accessing the file will never see any intermediate state) is important, write to a temporary file, close it, and then rename-over the old file. See for discussion e.g. How to write/replace files atomically?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.