Reputation: 203
Is there a way to use sed to replace starting of the string in the entire file without using a loop?
For example, my source data is the following:
str_address: 123 main street
str_desc: Apt3
str_desc: 2nd floor
str_city: new york
str_desc: mailing address
Now, the file will have thousands of addresses, but I want anytime "str_desc
" appears after "str_address
" and before "str_city
" to be replaced with "str_address
", however any "str_desc
" that appears after str_city
to remain unchanged.
Desired output:
str_address: 123 main street
str_address: Apt3
str_address: 2nd floor
str_city: new york
str_desc: mailing address
I can extract this info with,
cat file | awk '/str_city/{f=0} f; /str_address/{f=1}'
which gives
str_desc: Apt3
str_desc: 2nd floor
But I am having trouble changing the first "str_desc
" to "str_address
".
Upvotes: 1
Views: 133
Reputation: 52112
You can use an address range in sed:
$ sed '/str_address/,/str_city/s/str_desc/str_address/' infile
str_address: 123 main street
str_address: Apt3
str_address: 2nd floor
str_city: new york
str_desc: mailing address
This leaves all the str_desc
outside of the /str_address/,/str_city/
range untouched, and substitutes the others with str_address
(that's the s/str_desc/str_address/
part).
Upvotes: 1
Reputation: 881153
You almost have the complete solution in your awk
extraction code:
awk '/str_city/{f=0} f; /str_address/{f=1}'
The idea is to:
str_address
.str_city
.str_desc
with str_address
if the flag is on.That's basically (in readable form, and the order is important):
awk '
$1 == "str_address:" { flag = 1 }
$1 == "str_desc:" && flag == 1 { $1 = "str_address:" }
$1 == "str_city:" { flag = 0 }
{ print }
' < inputFile >outputFile
Here's a transcript showing it in action:
pax$ echo '
str_address: 123 main street
str_desc: Apt3
str_desc: 2nd floor
str_city: new york
str_desc: mailing address
' | awk '
$1 == "str_address:" { flag = 1 }
$1 == "str_desc:" && flag == 1 { $1 = "str_address:" }
$1 == "str_city:" { flag = 0 }
{ print }'
str_address: 123 main street
str_address: Apt3
str_address: 2nd floor
str_city: new york
str_desc: mailing address
And, of course, a minified version:
awk '$1=="str_address:"{f=1}$1=="str_desc:"&&f==1{$1="str_address:"}$1=="str_city:"{f=0}{print}' < inputFile >outputFile
Upvotes: 2