Search code examples
fileiojulia

How to edit a line of a file in julia?


I can read a file and find a special line based on a predicate like this

open(file, read=true, write=true, append=true) do io
    for line in eachline(io)
        if predicate(line)
            new_line = modifier(line)
            # how to replace the line with new_line in the file now?
        end
    end
end

But how can I change the content in the file now?


Solution

  • In general, you can't modify a file in-place (this is true for languages other than julia too), because adding or removing characters alters the positions of everything that comes after (a file is just one long string of bytes).

    So you can either

    1. read in your whole file, change what you want to change, and then write the whole file to the same location
    2. read line-by-line, write to a new location, and then copy the new file to the old location

    The latter is probably better in case you have really giant files (so you don't have to store the whole thing in memory). You've got most of the code, it's just a matter of creating a temp file, and then copying back to the original path at the end. Something like:

    (tmppath, tmpio) = mktemp()
    open(file) do io
        for line in eachline(io, keep=true) # keep so the new line isn't chomped
            if predicate(line)
                line = modifier(line)
            end
            write(tmpio, line)
        end
    end
    close(tmpio)
    mv(tmppath, file, force=true)
    

    NOTE: if this is at the global scope (eg, not inside a function), you might have to put global in front of tmpio inside the do block. Alternatively, wrap the whole thing in let. See here.