查找特定的子字符串,然后使用 shell 命令对下一个出现的变量执行更改 [关闭]

Posted

技术标签:

【中文标题】查找特定的子字符串,然后使用 shell 命令对下一个出现的变量执行更改 [关闭]【英文标题】:Look for particular substring and then perform changes to next occuring variable using shell command [closed] 【发布时间】:2021-12-16 02:27:06 【问题描述】:

我确实有一个如下 JSON 文件:-


  "Rules": [
    
      "ID": "DMS-FULL-HISTORY-DATA-DEEPARCHIVE-1d",
      "Filter": 
        "Prefix": "HISTORY/DATA/"
      ,
      "Status": "Enabled",
      "Transitions": [
        
          "Days": 1,
          "StorageClass": "DEEP_ARCHIVE"
        
      ]
    ,
    
      "ID": "FOL-FULL-HISTORY-DATA-DEEPARCHIVE-1d",
      "Filter": 
        "Prefix": "HISTORY/DATA/"
      ,
      "Status": "Enabled",
      "Transitions": [
        
          "Days": 1,
          "StorageClass": "DEEP_ARCHIVE"
        
      ]
    ,
    
      "ID": "Hello-CDC-delete-30d",
      "Filter": 
        "Prefix": "CDC/"
      ,
      "Status": "Enabled",
      "Expiration": 
        "Days": 30
      
    
  ]

我只想查找包含“-FULL-HISTORY-DATA”的规则 ID,然后将其状态更新为“已禁用”。休息文件保持不变。有没有办法在不使用单个 shell 命令或 sed 打开文件的情况下进行编辑?

期望的输出:-


  "Rules": [
    
      "ID": "DMS-FULL-HISTORY-DATA-DEEPARCHIVE-1d",
      "Filter": 
        "Prefix": "HISTORY/DATA/"
      ,
      "Status": "Disabled",
      "Transitions": [
        
          "Days": 1,
          "StorageClass": "DEEP_ARCHIVE"
        
      ]
    ,
    
      "ID": "FOL-FULL-HISTORY-DATA-DEEPARCHIVE-1d",
      "Filter": 
        "Prefix": "HISTORY/DATA/"
      ,
      "Status": "Disabled",
      "Transitions": [
        
          "Days": 1,
          "StorageClass": "DEEP_ARCHIVE"
        
      ]
    ,
    
      "ID": "Hello-CDC-delete-30d",
      "Filter": 
        "Prefix": "CDC/"
      ,
      "Status": "Enabled",
      "Expiration": 
        "Days": 30
      
    
  ]

我曾尝试使用 sed ,但这是对所有规则 ID 执行更新。

【问题讨论】:

请添加到您的问题(不发表评论):您搜索了什么,找到了什么?你尝试过什么,它是如何失败的? 鉴于您的上下文,看起来使用来自 bash 环境的 JSON 解析器会有很大帮助。您可能会欣赏jq(homepage,manual,SO 标签:jq) 或:How to modify JSON in groovy 我认为假设你不能从你的 groovy 环境中使用 JSON 解析器是一个错误。 Java 有 JSON 解析器,所以 Groovy 也有,如果你能够运行 bash 命令,就像你使用的标签似乎建议的那样,那么你可以运行 jq(尽管确保它安装在目标 bash env 上是另一个问题)。无论如何,提供一个不需要像基于 JSON 解析器的答案那样健壮的基于 sed 的答案很容易,所以我会努力解决这个问题 JSON 解析甚至是 Groovy/Gradle 内置的。例如,在 Gradle 构建脚本的上下文中调用 bash 脚本来修改 JSON 文件会适得其反。 【参考方案1】:

如果你真的想要sed 命令,可以使用以下命令:

sed '/.*FULL-HISTORY-DATA.*/N;N;N;N;s/"Status": "Enabled"/"Status": "Disabled"/'

你可以try it here。

每次sed 遇到包含“FULL-HISTORY-DATA”的行时,它都会消耗接下来的 4 行数据,并将其中的 "Status": "Enabled" 替换为 "Status": "Disabled"

这是一个非常脆弱的过程,因为 JSON 格式的任何不显着的更改都可能导致它失败,在少于 4 行中出现两次 FULL-HISTORY-DATA (第二次将在第一次被处理并获胜时被消耗) '没有被命令正确处理)。

如果您需要可靠且健壮的东西,您将需要使用 JSON 解析器。

【讨论】:

OK...那jq怎么走? 我添加了一个基于 jq 的答案。如果您的 jenkins 主机上未安装 jq,则最好使用 @léa-gris 提到的 groovy 中包含的 JSON 解析器。【参考方案2】:

如果jq 命令行 JSON 解析器可用,您可以使用以下命令:

jq '.Rules |= map((select(.ID | contains("FULL-HISTORY-DATA"))| .Status = "Disabled" ) // .)'

你可以try it online。

【讨论】:

以上是关于查找特定的子字符串,然后使用 shell 命令对下一个出现的变量执行更改 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

关于linux中字符串查找命令咨询

linux中ls命令会显示全部文件和文件夹,有啥办法只显示含特定字符的文件和文件夹

使用bash shell脚本从文件中查找和提取特定字符串后的值?

在 php 中使用 grep 命令在特定文件中查找字符串

将 shell 转义的参数字符串传递给 Bourne shell 中的子命令

批处理:在字符串中查找带引号的子字符串