TeX doesn't allow you to open files with append or overwrite permission: only read and write exist. You can fake that behavior by reading the file in, replacing what you want to replace, and then rewriting.
Here's an expl3 implementation of \replacelineonce and \replacelineall, which will replace one or all occurrences of a given string in the file. The syntax is:
\replacelineonce{<file>}{<search string>}{<replacement>}
{<true code>}{<false code>}
The code will read <file> line by line as strings (characters like \ and { etc. don't have their special meaning), looking for the <search string> (only full lines are matched), and if found, will replace by <replacement>. After replacing, the file is rewritten with the changed contents. If any replacement was made, <true code> is executed at the end, otherwise <false code> is executed. If the input file didn't exist, an error is raised and <false code> is executed. \replacelineonce will stop after the first replacement, while \replacelineall will replace all ocurrences.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \replacelineonce { m m m m m }
{ \mountain_replace_once:nnnTF {#1} {#2} {#3} {#4} {#5} }
\NewDocumentCommand \replacelineall { m m m m m }
{ \mountain_replace_all:nnnTF {#1} {#2} {#3} {#4} {#5} }
\tl_new:N \l__mountain_tmpa_tl
\tl_new:N \l__mountain_file_seq
\bool_new:N \l__mountain_replaced_bool
\ior_new:N \l__mountain_replace_ior
\iow_new:N \l__mountain_replace_iow
\prg_new_protected_conditional:Npnn \mountain_replace_once:nnn #1 #2 #3 { T, F, TF }
{ \__mountain_replace_aux:Nnnn \c_false_bool {#1} {#2} {#3} }
\prg_new_protected_conditional:Npnn \mountain_replace_all:nnn #1 #2 #3 { T, F, TF }
{ \__mountain_replace_aux:Nnnn \c_true_bool {#1} {#2} {#3} }
\cs_new_protected:Npn \__mountain_replace_aux:Nnnn #1 #2 #3 #4
{
\ior_open:NnTF \l__mountain_replace_ior {#2}
{ \__mountain_replace_line:Nnnn #1 {#3} {#4} {#2} }
{
\msg_error:nnn { mountain } { file-not-found } {#2}
\prg_return_false:
}
}
\cs_new_protected:Npn \__mountain_replace_line:Nnnn #1 #2 #3 #4
{
\seq_clear:N \l__mountain_file_seq
\bool_set_false:N \l__mountain_replaced_bool
\ior_str_map_inline:Nn \l__mountain_replace_ior
{
\str_if_eq:nnTF {##1} {#2}
{
\bool_set_true:N \l__mountain_replaced_bool
\seq_put_right:Nn \l__mountain_file_seq {#3}
\bool_if:NF #1
{ \ior_map_break:n { \__mountain_replace_skip: } }
}
{ \seq_put_right:Nn \l__mountain_file_seq {##1} }
}
\__mountain_replace_end:n {#4}
}
\cs_new_protected:Npn \__mountain_replace_skip:
{
\ior_str_map_inline:Nn \l__mountain_replace_ior
{ \seq_put_right:Nn \l__mountain_file_seq {##1} }
}
\cs_new_protected:Npn \__mountain_replace_end:n #1
{
\ior_close:N \l__mountain_replace_ior
\iow_open:Nn \l__mountain_replace_iow {#1}
\seq_map_inline:Nn \l__mountain_file_seq
{ \iow_now:Nn \l__mountain_replace_iow {##1} }
\iow_close:N \l__mountain_replace_iow
\bool_if:NTF \l__mountain_replaced_bool
{ \prg_return_true: }
{ \prg_return_false: }
}
\msg_new:nnn { mountain } { file-not-found }
{ File~`#1'~not~found. }
\ExplSyntaxOff
\begin{document}
\newwrite\tempfile
\immediate\openout\tempfile=lists.tex
\immediate\write\tempfile{line1}
\immediate\write\tempfile{}
\immediate\write\tempfile{line2}
\immediate\write\tempfile{}
\immediate\write\tempfile{line2}
\immediate\write\tempfile{}
\immediate\write\tempfile{line2}
\immediate\closeout\tempfile
\replacelineonce{lists.tex}{line2}{line replaced}
{Replaced once:}
{Nothing replaced:}
\input{lists}
\bigskip
\replacelineall{lists.tex}{line2}{line replaced}
{Replaced all:}
{Nothing replaced:}
\input{lists}
\bigskip
\replacelineonce{lists.tex}{line2}{line replaced}
{Replaced once:}
{Nothing replaced:}
\input{lists}
\bigskip
\end{document}