首页 > 解决方案 > 查找匹配的文本并替换 yml 中的下一行

问题描述

我正在尝试在 yml 配置文件中查找一行并将下一行替换为特定值。我尝试了 sed,但它似乎没有替换或找不到模式。下面是那个 yml 文件的片段

  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

我想将 applicationConnectors 的端口值更改14081因为adminConnectors存在另一个端口 脚本执行后,它应该如下所示:

  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

我试过下面的代码:

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

但似乎这段代码并没有取代任何东西。

标签: linuxawksed

解决方案


sed 最适合 s/old/new,仅此而已。对于其他任何事情,只需使用 awk 以提高清晰度、可移植性、稳健性等。看:

$ 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

acceptQueueSize:改为17吗?这是相同的脚本,只是变量值不同:

$ 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

sed如果您喜欢计算s ,请仅尝试使用您当前接受的解决方案n:-)。另请注意,无论行在每条记录中出现的顺序如何,这都会起作用,因为它关闭了名称port,而不是假设在 . 之后会出现特定数量的行applicationConnectors:。最后,即使您要搜索或替换的字符串包含 RE 元字符(例如.)、反向引用字符(例如\1or &)或 sed 分隔符(例如/),这也将起作用。


推荐阅读