I am trying to replace content in the previous line of a search.
My file:
<RECORD>
<TOKEN data = "670"/>
<ID data ="10647043"/>
<NAME data="m11111"/>
Here if I search for m11111, then I need to go to the previous line and replace 10647043 with a different value. Sed that I tried:
sed '/m11111/{g;/=/s/=.*/="9283"\/>/g;};h' test.txt
Is there a way with sed? If not with sed, any other way to do it ?
Thanks Ajay
Find and replace text within a file using sed command Use Stream EDitor (sed) as follows: sed -i 's/old-text/new-text/g' input.txt. The s is the substitute command of sed for find and replace. It tells sed to find all occurrences of 'old-text' and replace with 'new-text' in a file named input.txt.
The `sed` command can easily split on \n and replace the newline with any character. Another delimiter can be used in place of \n, but only when GNU sed is used. When the \n is missing in the last line of the file, GNU sed can avoid printing \n. Furthermore, \n is usually added to each consecutive output of `sed`.
In this syntax, you just need to provide the string you want to replace at the old string and then the new string in the inverted commas. After that, provide the file in which you want to find and replace the mentioned string.
\b marks a word boundary, either beginning or end. Now consider \b' . This matches a word boundary followed by a ' . Since ' is not a word character, this means that the end of word must precede the ' to match.
Assuming that test.txt
is not gigabytes in size and that you have GNU sed (gsed on a Mac), try:
$ sed -zE 's/10647043([^\n]*\n[^\n]*m11111)/9283\1/' test.txt
<RECORD>
<TOKEN data = "670"/>
<ID data ="9283"/>
<NAME data="m11111"/>
-z
This tells sed to read the whole file at once. Technically, it reads until NUL characters but, since no sensible text file has NUL characters, this is in practice the same as reading the whole file.
-E
This tells sed to use extended regular expressions so that we don't have to type so many backslashes.
s/10647043([^\n]*\n[^\n]*m11111)/9283\1/
This looks for 10647043 followed any any character except a newline, followed by a newline, followed any characters except a newline, follwed by m11111. This replace the 10647043 with 9283, keeping everything else the same.
sed -E 'H;1h;$!d;x; s/10647043([^\n]*\n[^\n]*m11111)/9283\1/' test.txt
The change here is the use of H;1h;$!d;x
to read the whole file in at once.
This reads in just one line at a time. If the current line contains m11111, then the previous line (stored in the variable last
) is modified.
$ awk '/m11111/{sub(/10647043/, "9283", last)} NR>1{print last} {last=$0} END {print last}' test.txt
<RECORD>
<TOKEN data = "670"/>
<ID data ="9283"/>
<NAME data="m11111"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With