Lunartist
Lunartist

Reputation: 464

Using awk(or sed) to replace specific group

For example, if I want to change 424, or any number, to 1 from below string.

<revision>424</revison>

I usually do this sed -i 's|<revision>.*</revision>|<revision>777</revision>|g and it works.

But I have to do a lot of similar commands
and I want to know if I can group like <revision>(.*)</revision> and replace only \1 to 777. How do I do this?

Upvotes: 1

Views: 110

Answers (2)

RavinderSingh13
RavinderSingh13

Reputation: 133518

With GNU awk and with your shown samples, please try following awk program. Simple explanation would be, using match function of awk and creating 4 capturing groups in it, where 1st group captures <revision>, 2nd one captures all Digits, 3rd one captures <\/revison> and 4th one(if there are any other values) everything. If this match function is true then printing 1st element of arr followed by newVal(awk variable which contains new value) followed by 3rd and 4th element value of arr.

awk -v newVal="777" '
match($0,/(<revision>)([0-9]+)(<\/revison>)(.*)/,arr){
  print arr[1] newVal arr[3] arr[4]
}
'  Input_file

Upvotes: 3

anubhava
anubhava

Reputation: 785146

Using gnu-sed you can use back-reference of a captured group in pattern matching like:

s='<revision>424</revision>'

sed -E 's~<(revision)>[0-9]*</\1>~<\1>777</\1>~g' <<< "$s"
<revision>777</revision>

However if you want to give perl a chance then you can even shorten it further with the use of look around assertions:

perl -pe 's~(?<=<(revision)>)\d*(?=</\1>)~777~g' <<< "$s"
<revision>777</revision>

Upvotes: 3

Related Questions