It appears that the sequence of the lines doesn't matter for your use case. Given that, I would use
ex and simply:
- Remove all instances of
- Insert the line you want.
You can do this like so:
printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . x | ex file.txt
The first command is to
delete all lines which match the regex
The next command is to
append after the last line (
$) the line
. ends the text to be appended.
x command saves changes and exits.
Each command is terminated by a newline by using
printf '%s\n' to send them to
Also see this very similar solution which I wrote a while back on the vi/Vim stack exchange.
To test the changes by printing the changed file to the command line without saving the changes, replace the
x with the two commands
%p 'q!' like so:
printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . %p 'q!' | ex file.txt
% means "entire buffer," which is what gets
q! means "quit, discarding changes."
To save the changes into a new file, replace the
w newfile.txt like so:
printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . 'w newfile.txt' 'q!' | ex file.txt
writes the modified buffer into
Alternatively you could do this at the start, to make a backup, and then save the changed file contents to the original location,
file.txt, like so:
printf '%s\n' 'w file.txt.bak' 'g/SMEAR/d' '$a' 'SMEAR=-5' . x | ex file.txt
Edit: Actually you don't need to use
q!; simply omitting the
x is enough to avoid saving changes. When
ex gets an EOF on trying to read further input, it will exit, and will not save changes.