linux - 找到匹配的文本并替换 yml 中的下一行

标签 linux awk sed

我试图在 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

我想将 applicationConnectorsport 值更改为 14081,因为 存在另一个 port>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

但是这段代码似乎没有替换任何东西。

最佳答案

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

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

关于linux - 找到匹配的文本并替换 yml 中的下一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55415380/

相关文章:

java - 尝试使用 update-java-alternatives 切换到 Java 6 后如何在 Ubuntu 中修复 Java

linux - 获取错误 install_driver(Oracle) 失败 : Can't load '/usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/DBD/Oracle/Oracle.so'

c++ - 由于 linux 中的 HRESULT 、 LARGE_INTEGER 和 DWORD 而出错

csv - 按列连接两行标题

AWK 用户定义函数 - 一种新语法?

java - 正则表达式:对匹配组执行操作

Android 应用程序和通过 USB 的通信

linux - 使用 shell 脚本或 awk 平均后两个文件之间的差异

linux - 替换匹配行中的某些位置

linux - 在 sed bash 中写一个特殊字符