Yuri van Geffen
Yuri van Geffen

Reputation: 983

sed: replace multiline

I'm trying to do a multiline replace using sed on OSX (zsh). My input file (Unity Asset file) looks like this:

...
displaySetting: 0
 applicationIdentifier:
  Android: com.appid.name
  Standalone: com.appid.name
  Tizen: com.appid.name
  iOS: com.appid.name
  tvOS: com.appid.name
buildNumber:
 iOS: 190
someOtherID: 190
moreIDsOverHere: 978987
...

I want to replace

buildNumber:
 iOS: 190

with

buildNumber:
 iOS: myBuildNumber

using the following command:

sed "N;s/^\\(.*buildNumber:.*.*$^.*iOS: \\)[0-9]*.*$/\\1myBuildNumber/;P;D" file.asset

This works except for it also removes the last line. I suspect this had something to do with my use of the pattern buffer, but I don't seem to be able to find a solution.

Help would be much appreciated!

Upvotes: 4

Views: 2175

Answers (2)

anubhava
anubhava

Reputation: 785098

Better to use awk for multiline record editing as:

awk '/buildNumber:/{p=NR} NR==p+1 && /iOS: [0-9]+/{sub(/iOS.*/, "iOS: myBuildNumber")} 1' file

dsplaySetting: 0
 applicationIdentifier:
  Android: com.appid.name
  Standalone: com.appid.name
  Tizen: com.appid.name
  iOS: com.appid.name
  tvOS: com.appid.name
buildNumber:
  iOS: myBuildNumber
someOtherID: 190
moreIDsOverHere: 978987

Upvotes: 2

SLePort
SLePort

Reputation: 15461

You don't need to use hold space here. Try this:

sed "/^[[:space:]]*buildNumber/{n;s/\(iOS: \)[0-9]*/\1myBuildNumber/;}" file

When buildNumber is found, n reads the next line and search for iOS: followed by numbers. If found, the pattern is replaced with iOS(using backreference) followed by myBuildNumber.

Edit:

To edit the file in place under OSX, add the -i flag:

sed -i '' "/^[[:space:]]*buildNumber/{n;s/\(iOS: \)[0-9]*/\1myBuildNumber/;}" file

Upvotes: 2

Related Questions