I have a script that needs to replace the first line that contains a specific phrase. It should not replace any other lines of text.
Using this:
sed -i '1,/old/ s/.*old.*/new/' temp
This correctly replaces the entire line containing 'old' with 'new'. But I noticed that if 'old' is on the first line, this does not work. I tried using 0 instead of 1 and it does not work at all, no replacements.
Please let me know if anyone has another way to do this that will also work on the first line.
The contents of the temp file are:
line 1 has 'old value' here.
line 2 has 'old value' here.
This is on an embedded device that uses sed
as part of BusyBox.
Versions are:
BusyBox v1.29.3 (2022-11-02 08:55:42 PDT) multi-call binary.
$ sed --version
This is not GNU sed version 4.0
$
The sed
C source from BusyBox is posted at: https://github.com/brgl/busybox/blob/master/editors/sed.c
By "this does not work", I assume you mean more lines are replaced than desired.
You are using the substitute command inside a range test.
The form is: address1 ,
address2 command
Addresses are generally specified as an absolute number, $
(final line of file), or a regular expression.
The significant point is that the test for address2 does not happen until the line after the line that matches address1.
In your command:
1
= address1/old/
= address2This means /old/
is not checked until line 2.
GNU sed has a non-standard extension where address1 can be 0
, which is taken to mean that the range begins at the start of the file (a notional line zero) and testing for address2 begins from the first line. It seems busybox sed does not support that extension.
You could rewrite your script as, for example:
sed -i '
/.*old.*/!b
s//new/
:loop
n
bloop
' temp
Specifying an empty regex to s///
reuses the last RE used in the last command applied.