简体   繁体   中英

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.

Since the port line is the second after applicationConnectors: you need to use double n; and you should use double quotation marks around the sed command to allow variable interpolation inside:

sed "/applicationConnectors:/{n;n;s/\($var2\).*/\1: ${var1}/}" configuration.yml > newfile

See this online sed demo .

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 n s :-). 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 (eg . ), backreference chars (eg \\1 or & ), or sed delimiters (eg / ).

staging:
  datasource:
    jdbcUrl: xxx
    driverclassname: yyy
    username: zzzz
    password: dddd
    platform: wwww

sed command to replace value of jdbc url :

sed -i "/staging:/{n;n;s/\(jdbcUrl\).*/\1: AAAAA/}" application.yml

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM