Search code examples
sedshposixportability

Replace one matched pattern with another in multiline text with sed


I have file with this text:

mirrors:
  docker.io:
    endpoint:
      - "http://registry:5000"
  registry:5000:
    endpoint:
      - "http://registry:5000"
  localhost:
    endpoint:
      - "http://registry:5000"

I need to replace it with this text in POSIX shell script (not bash):

mirrors:
  docker.io:
    endpoint:
      - "http://docker.io"
  registry:5000:
    endpoint:
      - "http://registry:5000"
  localhost:
    endpoint:
      - "http://localhost"

Replace should be done dynamically in all places without hard-coded names. I mean we should take sub-string from a first line ("docker.io", "registry:5000", "localhost") and replace with it sub-string "registry:5000" in a third line.

I've figure out regex, that splits it on 5 groups: (^ )([^ ]*)(:[^"]*"http:\/\/)([^"]*)(")

Then I've tried to use sed to print group 2 instead of 4, but this didn't work: sed -n 's/\(^ \)\([^ ]*\)\(:[^"]*"http:\/\/\)\([^"]*\)\("\)/\1\2\3\2\5/p'

Please help!


Solution

  • This might work for you (GNU sed):

    sed -E '1N;N;/\n.*endpoint:.*\n/s#((\S+):.*"http://)[^"]*#\1\2#;P;D' file 
    

    Open up a three line window into the file.

    If the second line contains endpoint:, replace the last piece of text following http:// with the first piece of text before :

    Print/Delete the first line of the window and then replenish the three line window by appending the next line.

    Repeat until the end of the file.