Is there a native Julia command to write to a particular line of a file? I know how to open a file, namely using open, but it seems like the options are to overwrite the entire file (with the “w” and write commands/options), or write to its end (with the “a” and write commands/options). I haven’t found an option to specify a line to add content to.
I know that if all else fails, I could use:
run(`sed -i "$line i What I want to write" $file`)
But I’m wondering whether there’s another way that just uses Julia commands and no external commands.
2 Likes
Here is one way to do this:
julia> function skiplines(io::IO, n)
i = 1
while i <= n
eof(io) && error("File contains less than $n lines")
i += read(io, Char) === '\n'
end
end
skiplines (generic function with 1 method)
julia> # write 3 lines to test.foo
write("test.foo", "foo\nbar\nbaz\n")
12
julia> f = open("test.foo", "r+")
IOStream(<file test.foo>)
julia> skiplines(f, 2)
julia> # seek stream back before the last '\n'
skip(f, -1)
IOStream(<file test.foo>)
julia> # mark current stream position, so we can seek back later
mark(f)
7
julia> buf = IOBuffer()
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)
julia> # write rest of file into buf
write(buf, f)
5
julia> seekstart(buf)
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=5, maxsize=Inf, ptr=1, mark=-1)
julia> # go back to the end of the 2nd line we marked earlier
reset(f)
7
julia> print(f, "bara")
julia> # now write rest of file from buf back into f
write(f, buf)
5
julia> close(f)
julia> Text(read("test.foo", String))
foo
barbara
baz
4 Likes
I tried copy-pasting your code into a function, editL
. Here it is:
function editL(file, string, no)
write(file, string);
f = open(file, "r+");
skiplines(f, no);
skip(f, -1)
mark(f)
buf = IOBuffer()
write(buf, f)
seekstart(buf)
reset(f)
write(f, buf)
close(f)
end
and it doesn’t do what I expected, it actually deletes the whole file and adds string
(the contents of that third argument, not the word string) to it.
Delete the first line. The first write
is just to create the file test.foo for this demonstration.
Turns out your code also solves Writing LaTeX from Julia.