我正在尝试使用jq
自动将i18n字符串文件从一个库采用的格式更改为另一个库。
我有一个json文件,它看起来像这样:
{
"some_label": {
"message": "a string in English with a $VARIABLE$",
"description": "directions to translators",
"placeholders": {
"VARIABLE": {
"content": "{variable}"
}
}
},
// more of the same...
}
我需要它来打开"some-label": "a string in English with a {variable}"
我非常接近得到它。目前,我正在使用
jq '[.
| to_entries
| .[]
| .key |= (gsub("_";"-"))
| .value.placeholders as $p
| .value.message |= (sub("\$KEY_NAME\$";$p.KEY_NAME.content))
| .value = .value.message
] | from_entries'
下一步是在sub
调用中使用捕获组,这样我就可以通过编程获得具有不同名称的变量,但我不知道如何使用捕获组索引到$p
中。
我试过sub("\$(?<id>VARIABLE)\$";$p.(.id).content)
,它给出了一个编译器错误,我几乎不知道下一步该怎么做。
以下是实现所需结果的一种方法。它也可以进一步简化。在顶层,它通过将整个过滤器封装在with_entries()
下并根据需要修改.value
字段来删除to_entries
/from_entries
的使用
with_entries(
.key |= ( gsub("_";"-") ) |
.value.placeholders as $p |
.value.message as $m |
( $m | match(".*\$(.*)\$") | .captures[0].string ) as $c |
( $p | .[$c].content ) as $v |
( "\$" + $c + "\$" ) as $t |
.value = ( $m | sub($t; $v) )
)
我认为表达的关键部分是
- 部件
$m | match(".*\$(.*)\$") | .captures[0].string
进行正则表达式匹配,以提取.message
中$..$
内的部件 - 部分
$p | .[$c].content
使用$c
的动态值进行一般对象索引提取 - 由于
sub()
/gsub()
函数的第一个自变量是正则表达式,因此需要将捕获的值$c
创建为\$VARIABLE\$
jqplay-演示
这里有一个基本的JQ。没有尝试过复杂的输入,也没有适应$
。我想你可以在此基础上进行构建-
to_entries | map(. as $kv | { "($kv.key)": $kv.value.placeholders | to_entries | map(. as $p | $kv.value.message | sub("\$($p.key)\$"; $p.value.content))[0]}) | add
输出-
{
"some_label": "a string in English with a {variable}"
}