Skip to content
Advertisement

find matching text and replace next line in yml

I’m trying to find a line in a yml configuration file and replace the next line with a specific value. I tried sed, but it seems it is not replacing or not able to find the pattern. Below is the snippit of that yml file

  applicationConnectors:
    - type: http
      port: 14080
      bindHost: 15.213.48.154
      headerCacheSize: 512 bytes
      outputBufferSize: 32KiB
      maxRequestHeaderSize: 8KiB
      maxResponseHeaderSize: 8KiB
      inputBufferSize: 8KiB
      idleTimeout: 30 seconds
      minBufferPoolSize: 64 bytes
      bufferPoolIncrement: 1KiB
      maxBufferPoolSize: 64KiB
      acceptorThreads: 1
      selectorThreads: 2
      acceptQueueSize: 1024
      reuseAddress: true
      useServerHeader: false
      useDateHeader: true
      useForwardedHeaders: true

  adminConnectors:
    - type: http
      port: 14180

I want to change port value to 14081 for applicationConnectors as there is another port exists for adminConnectors After the script execution it should look like:

  applicationConnectors:
    - type: http
      port: 14081
      bindHost: 15.213.48.154
      headerCacheSize: 512 bytes
      outputBufferSize: 32KiB
      maxRequestHeaderSize: 8KiB
      maxResponseHeaderSize: 8KiB
      inputBufferSize: 8KiB
      idleTimeout: 30 seconds
      minBufferPoolSize: 64 bytes
      bufferPoolIncrement: 1KiB
      maxBufferPoolSize: 64KiB
      acceptorThreads: 1
      selectorThreads: 2
      acceptQueueSize: 1024
      reuseAddress: true
      useServerHeader: false
      useDateHeader: true
      useForwardedHeaders: true

  adminConnectors:
    - type: http
      port: 14180

I have tried below code:

var1="14081"
var2="port"
sed '/applicationConnectors:/{n;s/($var2).*$/1${var1}/}' configuration.yml > newfile
mv newfile configuration.yml

but it seems this code is not replacing anything.

Advertisement

Answer

sed is best for s/old/new, that is all. For anything else just use awk for clarity, portability, robustness, etc. Look:

$ awk -v rec='applicationConnectors' -v tag='port' -v val='14081' '
    /^  [^ ]/{name=$1} name==(rec":") && $1==(tag":"){sub(/[^ ]+$/,""); $0=$0 val}
1' file
  applicationConnectors:
    - type: http
      port: 14081
      bindHost: 15.213.48.154
      headerCacheSize: 512 bytes
      outputBufferSize: 32KiB
      maxRequestHeaderSize: 8KiB
      maxResponseHeaderSize: 8KiB
      inputBufferSize: 8KiB
      idleTimeout: 30 seconds
      minBufferPoolSize: 64 bytes
      bufferPoolIncrement: 1KiB
      maxBufferPoolSize: 64KiB
      acceptorThreads: 1
      selectorThreads: 2
      acceptQueueSize: 1024
      reuseAddress: true
      useServerHeader: false
      useDateHeader: true
      useForwardedHeaders: true

  adminConnectors:
    - type: http
      port: 14180

Want to change acceptQueueSize: to 17 instead? It’s the same script with just different variable values:

$ awk -v rec='applicationConnectors' -v tag='acceptQueueSize' -v val='17' '
    /^  [^ ]/{name=$1} name==(rec":") && $1==(tag":"){sub(/[^ ]+$/,""); $0=$0 val}
1' file
  applicationConnectors:
    - type: http
      port: 14080
      bindHost: 15.213.48.154
      headerCacheSize: 512 bytes
      outputBufferSize: 32KiB
      maxRequestHeaderSize: 8KiB
      maxResponseHeaderSize: 8KiB
      inputBufferSize: 8KiB
      idleTimeout: 30 seconds
      minBufferPoolSize: 64 bytes
      bufferPoolIncrement: 1KiB
      maxBufferPoolSize: 64KiB
      acceptorThreads: 1
      selectorThreads: 2
      acceptQueueSize: 17
      reuseAddress: true
      useServerHeader: false
      useDateHeader: true
      useForwardedHeaders: true

  adminConnectors:
    - type: http
      port: 14180

Only try that with your currently accepted sed solution if you enjoy counting ns :-). Note also that this will work no matter what order the lines appear within each record since it keys off the name port rather than assuming that will appear some specific number of lines after applicationConnectors:. Finally, this will work even if the strings you’re searching for or replacing with contain RE metachars (e.g. .), backreference chars (e.g. 1 or &), or sed delimiters (e.g. /).

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement