使用 JQ 替换 JSON 中的下划线

Posted

技术标签:

【中文标题】使用 JQ 替换 JSON 中的下划线【英文标题】:Replacing underscores in JSON using JQ 【发布时间】:2017-03-14 23:21:00 【问题描述】:

我正在使用woocommerce API 来检索和存储信息。目前,我们的设置旨在使用驼峰式大小写而不是下划线。我正在使用jq 来处理我们的信息,但我很好奇如何使用sub(regex, tostring) 函数将JSON 中的下划线替换为camelCase?

这是代码示例

"line_items": [
    
     "id": xxxx,
     "name": "xxxx",
     "sku": "xxxx",
     "product_id": xxxx,
    

例如,根据我发现的关于 SO 的另一个答案,这是有效的:curl https://www.testsite.com/wp-json/wc/v1/orders -u user:pass | jq '.[] | with_entries( if .key | contains("_") then .key |= sub("_";"") else . end)' 并删除下划线。

结果是:

"lineitems": [
    
     "id": xxxx,
     "name": "xxxx",
     "sku": "xxxx",
     "productid": xxxx,
    

但是,当我尝试curl https://www.testsite.com/wp-json/wc/v1/orders -u user:pass | jq '.[] | with_entries( if .key | contains("_") then .key |= sub("(\\_)([a-z])";"$2\u") else . end)' 时,我没有得到预期的结果。

预期的结果是:

"lineItems": [
    
     "id": xxxx,
     "name": "xxxx",
     "sku": "xxxx",
     "productId": xxxx,
    

我没有太多使用 jq 的经验,所以我不确定自己做错了什么。有没有更好的办法解决这个问题?

【问题讨论】:

【参考方案1】:

这是一个 jq 函数,它将“a_bcd_ef”转换为“aBcdEf”,这似乎是你想要的:

def camel:
  gsub( "_(?<a>[a-z])"; .a|ascii_upcase);

示例用法:

"a_bcd_ef" | camel

如果你想要一个简单的单行来处理来自 STDIN 的 JSON 字符串:

$ jq 'gsub( "_(?<a>[a-z])"; .a|ascii_upcase)'

如果您只想转换第一次出现的“_[a-z]”,那么您当然会使用sub。以此类推。

要将此函数应用于对象中的所有键,您可以编写:

with_entries( .key |= camel )

要更改 JSON 实体中所有对象中的所有键,您可以使用 walk/1

walk(if type == "object" then with_entries(.key |= camel) else . end)

如果您的 jq 没有 walk/1,那么您可以简单地包含它的定义(通过谷歌搜索很容易找到),或者在它被调用之前,或者可能在您的 ~/.jq 文件中。

【讨论】:

【参考方案2】:

虽然不如@peak的gsub解决方案简洁,但这个更直观,更容易让初学者理解恕我直言。

您可以将其放入名为“snake_to_camel.jq”和chmod +x snake_to_camel.jq的脚本中

#!/usr/bin/env jq -f
def head:
  .[0:1];

def tail:
  .[1:];

def capitalize:
  (head | ascii_upcase) + tail;

def snake_to_camel:
  split("_") |
  head + (tail | map(capitalize)) |
  join("");

def map_keys(mapper):
  walk(if type == "object" then with_entries(.key |= mapper) else . end);

map_keys(snake_to_camel)

示例用法:

curl https://example.com/input.json | ./snake_to_camel.jq

我在这里使用的一些 jq 功能:

slices 头部和尾部 ascii_upcase addition 用于数组连接 split 和 join walk with_entries

【讨论】:

以上是关于使用 JQ 替换 JSON 中的下划线的主要内容,如果未能解决你的问题,请参考以下文章

eclipse - 查找并替换变量名称中的下划线字符

Netezza 用下划线替换空白

用下划线替换 URL 中的空格

使用 Jbuilder 而不是下划线的 json 键中的连字符

如何用破折号替换codeigniter url中的下划线?

用空格替换要素名称中的所有下划线