使用JQ替换JSON中的下划线

8

我正在使用WooCommerce API来获取和存储信息。目前,我们的设置是设计为使用驼峰式而不是下划线。我使用jq处理我们的信息,但我想知道如何使用sub(regex, tostring)函数将JSON中的下划线替换为驼峰式?

以下是代码示例:

"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的很多经验,所以不确定我的做法是否正确。有更好的解决方案吗?

2个回答

14
这是一个jq函数,可以将"a_bcd_ef"转换为"aBcdEf",似乎符合您的要求:

下面是该函数代码:

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

示例用法:

"a_bcd_ef" | camel
如果您想要一个简单的一行命令来处理来自标准输入的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 文件中。


6

虽然不如@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 特性:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接