【问题标题】:Search segment and append value at the end搜索段并在末尾附加值
【发布时间】:2021-01-27 23:37:46
【问题描述】:

在一个文件中,我想在带有键“sys-mgmt-agent”的特定段之后附加一个字符串。 这是文件内容:

  sys-mgmt-agent:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z

  edge-orchestrator:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z

这是预期的结果:

  sys-mgmt-agent:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
    MY STRING

  edge-orchestrator:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z

我使用 sed 命令找到了该段:sed -n '/sys-mgmt-agent:/,/^\s*$/p' <file>,但我无法附加我的字符​​串。

【问题讨论】:

  • 恕我直言,专家总是建议使用yq 之类的工具,它可以更好地理解 yaml 文件。您的系统中是否有yq 或者您可以安装它?根据您的回复,人们可以在此处为您提供指导。
  • 不,我无法在远程服务器上安装软件。

标签: regex linux bash sed


【解决方案1】:

基于 OP 的 sed 想法 sed 尝试:

$ mystring='MY STRING'
$ sed "/sys-mgmt-agent:/,/^$/{/^$/i\    ${mystring}
}" mydata

地点:

  • /sys-mgmt-agent/,/^$/ - 搜索范围
  • {...} - 应用于匹配范围的命令
  • /^$/i\ ${mystring} - 在空白行插入新行“我的字符串”

注意i\ ${mystring} 在同一行后面不能有任何内容,因此是 2 行解决方案;我愿意接受有关如何将其折叠成一行的建议。


更新:@potong 建议使用-e 标志拼凑一个单行解决方案,并在${mystring} 周围添加双引号:

$ mystring='MY STRING'
$ sed -e '/sys-mgmt-agent:/,/^$/{/^$/i\    '"${mystring}" -e '}' mydata

以上生成:

  sys-mgmt-agent:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
    MY STRING

  edge-orchestrator:
    networks:
     edgex-network:
       aliases:
           - edgex-sys-mgmt-agent
    depends_on:
      - redis
    volumes:
      - /proc/uptime:/proc/uptime
      - /var/log/auth.log:/var/log/auth.log
      - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z

【讨论】:

  • 谢谢,如果有办法在单行中使用命令,请告诉我。
  • @sarjaana 你可以试试:sed -e '/sys-mgmt-agent:/,/^$/{/^$/i\ '${mystring} -e '}' file
【解决方案2】:

这可能对你有用(GNU sed):

sed '/sys-mgmt-agent:/{:a;/:$/h;n;/\S/{$!ba;p};x;s/\S.*/MY STRING/p;x;$d}' file

注意如果MY STRING 包含/,这些必须被转义/引用,即\/。这也缩进到最后一节的深度。

【讨论】:

    【解决方案3】:

    假设:

    • OP 坚持使用bash 下可用的基本命令
    • 输入的格式很好,如图所示
    • 如果sys-mgmt-agent: 出现多次,则需要将所需字符串附加到每个段
    • 段之间至少有一个空行

    一个awk解决方案:

    $ mystring="MY STRING"                         # string to be appended to segment
    $ awk -v ms="${mystring}" '                    # pass ${mystring} as awk variable "ms" 
    /sys-mgmt-agent:/ { foundit=1 }                # if line contains "sys-mgmt-agent:" then set our flag
    /^$/ && foundit { printf "    %s\n\n", ms      # if blank line and foundit=1 then print our string plus a new blank line
                      foundit=0                    # reset our flag
                      next                         # go to next input line
                    }
                    { print }                      # print all other lines as is
    ' mydata                                       # assuming input data is in file named "mydata"
    

    以上生成:

    sys-mgmt-agent:
      networks:
       edgex-network:
         aliases:
             - edgex-sys-mgmt-agent
      depends_on:
        - redis
      volumes:
        - /proc/uptime:/proc/uptime
        - /var/log/auth.log:/var/log/auth.log
        - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
      MY STRING
    
    edge-orchestrator:
      networks:
       edgex-network:
         aliases:
             - edgex-sys-mgmt-agent
      depends_on:
        - redis
      volumes:
        - /proc/uptime:/proc/uptime
        - /var/log/auth.log:/var/log/auth.log
        - ${HOST_SECURITY_FILE_PATH}edgex-redis:/tmp/edgex/secrets/edgex-redis:z
    

    【讨论】:

      猜你喜欢
      • 2012-06-20
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 2019-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多