Groovy字符串用变量中的美元符号替换令牌无效

Groovy字符串用变量中的美元符号替换令牌无效,groovy,jenkins-groovy,Groovy,Jenkins Groovy,我的values-dev.yaml文件如下 props = readProperties file: "src/main/resources/application-DEV.properties"; def DB_HOST = (props['com_db_url'].split(':')[2]).replace('//', ''); def DB_USER = props['com_db_username']; def DB_PASSWOR

我的values-dev.yaml文件如下

props = readProperties  file: "src/main/resources/application-DEV.properties";
def DB_HOST         = (props['com_db_url'].split(':')[2]).replace('//', '');
def DB_USER         = props['com_db_username'];
def DB_PASSWORD     = props['com_db_password'];
def DB_PORT         = (props['com_db_url'].split(':')[3]).split('/')[0];
def jsonData = "{'$DB_HOST':'${DB_HOST}','$DB_USER':'${DB_USER}','$DB_PASSWORD':'${DB_PASSWORD}','$DB_PORT':'${DB_PORT}'}";
String filenew = readFile('dev/values-dev.yaml')
def jsonObject = readJSON text: jsonData;

jsonObject.each { key, value ->
    def _key = "${key}";
    _key = '\\\\'+_key
    echo "$key : $value, custom key : ${_key}"
    filenew = filenew.replaceAll("${_key}", '$value')
}

在过去的4天里,我尝试了多种方法来替换循环使用的令牌,但运气不好。 按照下面的方法,它对我有效

resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi
config:
  autoDiscoverDatabases: true
  datasource:
    host: $DB_HOST
    user: $DB_USER
    password: $DB_PASSWORD
    port: $DB_PORT
    sslmode: "require"
    database: "ibmclouddb"
我特意在JSON数据中预先添加了$symbol变量,即在上面最初声明的jsonData变量中


但是我想通过一种通用的方法来实现这一点。

所有替换都可以在一个步骤中完成,无需使用 临时JSON映射

只要用你知道的所有替代品建立一张地图。然后使用 使用regexp替换所有,该regexp捕获替换密钥并使用 用于处理更换件的封口。闭包只是查找 输入替换项,并有一些方法生成错误,如果 替换项未知,或者您可以将密钥写回

//filenew = filenew.replaceAll('\\$DB_HOST', jsonObject.DB_HOST)
//filenew = filenew.replaceAll('\\$DB_USER', jsonObject.DB_USER)
//filenew = filenew.replaceAll('\\$DB_PASSWORD', jsonObject.DB_PASSWORD)
//filenew = filenew.replaceAll('\\$DB_PORT', jsonObject.DB_PORT)

所有更换都可以一步完成,无需使用 临时JSON映射

只要用你知道的所有替代品建立一张地图。然后使用 使用regexp替换所有,该regexp捕获替换密钥并使用 用于处理更换件的封口。闭包只是查找 输入替换项,并有一些方法生成错误,如果 替换项未知,或者您可以将密钥写回

//filenew = filenew.replaceAll('\\$DB_HOST', jsonObject.DB_HOST)
//filenew = filenew.replaceAll('\\$DB_USER', jsonObject.DB_USER)
//filenew = filenew.replaceAll('\\$DB_PASSWORD', jsonObject.DB_PASSWORD)
//filenew = filenew.replaceAll('\\$DB_PORT', jsonObject.DB_PORT)

这里有一个更简单的解决方案,它可以按照您的意愿以通用的方式工作

def replacements = [
  DB_USER: "the user",
  // ...
]

def yaml = '''
config:
  autoDiscoverDatabases: true
  datasource:
    host: $DB_FAILS
    user: $DB_USER
'''

println yaml.replaceAll(/\$([A-Z_]+)/, { _, k -> replacements.getOrDefault(k, "FAILED TO REPLACE $k") })
// →
// config:
//   autoDiscoverDatabases: true
//   datasource:
//     host: FAILED TO REPLACE DB_FAILS
//     user: the user
对于输出:

import groovy.json.JsonSlurper

String props = '''
    user: $DB_USER
    pass: $DB_PASS
'''

def DB_USER = 'com_db_username'
def DB_PASS = 'com_db_password'
def jsonData = $/
    {
        "$$DB_USER":"${DB_USER}",
        "$$DB_PASS":"${DB_PASS}",
    }/$

//println jsonData

def jsonObject =  new JsonSlurper().parseText(jsonData)
jsonObject.each { key, value ->
    props = props.replaceAll(/\$key/, value)
}
println props
最棘手的部分是正则表达式和转义,以及使用什么样的字符串来方便转义。在正则表达式/\$key/中,$key的exapended值将是$DB\u USER,它将输出$sign,该符号也必须用\ before转义

我不得不修改你的代码,在没有Jenkins服务器的情况下工作。 我必须纠正的一个错误是,JSON没有对键值使用双引号。为了在不破坏插值的情况下修复它,我使用了一个groovy dollar slashy字符串,它更具可读性和灵活性。在$-slashy字符串中,您只需要转义$符号,其他所有内容都可以保持原样而不转义。
为了简单起见,我没有使用yaml文件,而是只使用字符串。对于属性,我定义了一些变量,并将所有变量减少为2个变量。

这里有一个更简单的解决方案,可以按照您的意愿以通用方式工作

def replacements = [
  DB_USER: "the user",
  // ...
]

def yaml = '''
config:
  autoDiscoverDatabases: true
  datasource:
    host: $DB_FAILS
    user: $DB_USER
'''

println yaml.replaceAll(/\$([A-Z_]+)/, { _, k -> replacements.getOrDefault(k, "FAILED TO REPLACE $k") })
// →
// config:
//   autoDiscoverDatabases: true
//   datasource:
//     host: FAILED TO REPLACE DB_FAILS
//     user: the user
对于输出:

import groovy.json.JsonSlurper

String props = '''
    user: $DB_USER
    pass: $DB_PASS
'''

def DB_USER = 'com_db_username'
def DB_PASS = 'com_db_password'
def jsonData = $/
    {
        "$$DB_USER":"${DB_USER}",
        "$$DB_PASS":"${DB_PASS}",
    }/$

//println jsonData

def jsonObject =  new JsonSlurper().parseText(jsonData)
jsonObject.each { key, value ->
    props = props.replaceAll(/\$key/, value)
}
println props
最棘手的部分是正则表达式和转义,以及使用什么样的字符串来方便转义。在正则表达式/\$key/中,$key的exapended值将是$DB\u USER,它将输出$sign,该符号也必须用\ before转义

我不得不修改你的代码,在没有Jenkins服务器的情况下工作。 我必须纠正的一个错误是,JSON没有对键值使用双引号。为了在不破坏插值的情况下修复它,我使用了一个groovy dollar slashy字符串,它更具可读性和灵活性。在$-slashy字符串中,您只需要转义$符号,其他所有内容都可以保持原样而不转义。
为了简单起见,我使用字符串代替yaml文件,对于属性,我定义了一些变量,并将所有变量减少为2个。

Hi@cfrick我总是得到空值`datasource:22:51:37主机:无法替换空值22:51:37用户:无法替换空值22:51:37密码:无法替换空值22:51:37端口:无法替换空值`Hi@cfrick我总是获取null值`datasource:22:51:37主机:无法替换null 22:51:37用户:无法替换null 22:51:37密码:无法替换null 22:51:37端口:无法替换null`此解决方案面临的问题是,我无法导入JsonSplurr库,因为我们对导入任何外部库都有限制。这里限制太多了。我只需要坚持基本的自由泳,你不必。我之所以使用它,是因为我在本地机器上测试了它,在那里我没有readJson,而readJson只在Jenkins上可用。只要用示例中的readJson替换JsonSlurper,一切都正常。我需要修改我的JSON数据结构吗?因为您在键端提到了两个美元符号,如下:-$$DB_USER:${DB_USER},有必要吗?没有。我使用了美元slashy字符串,因为它在转义字符串时更方便。它使一切都更具可读性。有没有其他更简单的方法不包括美元符号?因为这仍然依赖于角色。如果我从字符串中删除美元符号,它可以正常工作,但不会替换令牌。我面临的这个解决方案的问题是,我无法导入JsonSplurr lib,因为我们对导入任何外部库都有限制。这里限制太多了。我只需要坚持基本的自由泳,你不必。我之所以使用它,是因为我在本地机器上测试了它,在那里我没有readJson,而readJson只在Jenkins上可用。只要用示例中的readJson替换JsonSlurper,一切都正常。我需要修改JSON数据结构吗
e?,因为您在键侧提到了两个美元符号,如下:-$$DB_USER:${DB_USER},是否有必要?没有。我使用了美元斜线字符串,因为它在转义字符串时更方便。它使一切都更具可读性。有没有其他更简单的方法不包括美元符号?因为这仍然依赖于角色。如果我从字符串中删除美元符号,它将正常工作,但不会替换令牌。