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
SMEAR
;
- 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 g
lobally d
elete all lines which match the regex /SMEAR/
.
The next command is to a
ppend after the last line ($
) the line SMEAR=-5
. The .
ends the text to be appended.
The x
command saves changes and exits.
Each command is terminated by a newline by using printf '%s\n'
to send them to ex
.
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 p
rinted.
q!
means "quit, discarding changes."
To save the changes into a new file, replace the %p
with w newfile.txt
like so:
printf '%s\n' 'g/SMEAR/d' '$a' 'SMEAR=-5' . 'w newfile.txt' 'q!' | ex file.txt
This w
rites the modified buffer into newfile.txt
.
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.