Simple txt file read, find word, manipulate and write new file

Hello,

I'm trying to read a txt file, load it into memory / buffer then manipulate it i.e. search for word in line and if found change it... then after having read all the lines, will write a new txt file... I'm kinda stuck with this... Haven't had the time to study / learn Rust properly. Something I could do in Python or Javascript is proving to be monumentally difficult with Rust. I can't choose the other two languages because I need a small EXE file... so far I've got the following.

    let oldfile = File::open("old.txt")?;
    let transcoded = DecodeReaderBytesBuilder::new()
        .encoding(Some(UTF_16LE))
        .build(oldfile);
    let mut buffered = BufReader::new(transcoded);

    for line in buffered.lines() { 
        println!("{:?}", line?);
        println!("*****************************************")
    }

it'll std out or print the lines but I can't for the life of me figure out what to do... do i put the lines into a vector of sorts and then do some type of function to search for word and modify it in the vector? After which I use some type of writer to a new file? Or can I manipulate it right in the memory? This is an monumental paradigm shift from dynamically typed languages.

Is this way of doing things even right? Or am I completely missing the mark?

Thanks in advanced.

It's not clear exactly what the challenge is. There are many options. For example, if you are just modifying each line, you can write as you go along:

let mut out = File::create("output.txt")?;
for line in buffered.lines() {
    let line = line?; // handle errors
    writeln!(out, "The line was {}.", line)?;
}

You can also read the entire file into memory and handle it there. E.g. to reverse the lines in a file:

let mut input = BufReader::new(File::open("input.txt")?);
let mut out = File::create("output.txt")?;

let mut vec = Vec::new();

for line in input.lines() {
    vec.push(line?);
}
vec.reverse();
for line in &vec {
    writeln!(out, "{}", line)?;
}

You might get better performance if you wrap the output File in a BufWriter.

Thanks alot for your prompt reply, the files will always be small (no more than 40kb in size), so loading the entire file looks favourable... but is there a way to do a search / replace keywords?

Say I use the second option to load the entire file in memory... what's a good way to do a search / replace for keywords.

Sorry this is a noob question. But really need to get this done for work tomorrow and it's 1:22 am lol

thanks,

For simple replacing, you can use replace from the standard library.

let mut input = BufReader::new(File::open("input.txt")?);
let mut out = File::create("output.txt")?;

let mut vec = Vec::new();

for line in input.lines() {
    vec.push(line?.replace("a", "b"));
}
for line in &vec {
    writeln!(out, "{}", line)?;
}

For more sophisticated replacing, you can use the regex crate.

1 Like

Thanks Alice, I really appreciate it. That should get me by.

Thanks again.

You're welcome.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.