This looks like you erroneously put an s
before the first slash. s/regex/replacement/
replaces matches of regex
with the text replacement
, whereas just /regex/
is an address expression which selects lines which match regex
.
You also put the replacement in a weird place, but your second attempt looks fixable with fairly minor changes. Try
sed -i -e '/'"$tmproll"'/{N;s/\n.*/\nName: '"$tmpName"'/;}' "$filename"
Notice also the quoting fixes; see also When to wrap quotes around a shell variable? (the quoting could actually be simplified quite a bit by switching to double quotes altogether).
In more detail, a sed
script consists of a sequence of address command pairs. The address is optional; in its absence, the command is applied to every input line. This script contains the commands N
(fetch the next input line, so that the pattern space contains both the original line and the following one, separated by a newline character) and s/regex/replacement/
to replace the text after the newline character (i.e. the new line we fetched with N
) with new text. The commands are inside braces to say they all should be applied if the address expression matched.
Using sed
for any non-trivial logic tends to produce write-only scripts; this would arguably be easier to write and understand in Awk.
awk -v no="$tmproll" -v name="$tmpName" '/Roll no / && $4 == no { replace=1 }
/Name / && replace { $3=name }1' "$filename"
You will need to write the result to a temporary file and then rename it if you don't have GNU Awk, which has an inplace
facility similar to sed -i
.