使用 |= 更新赋值时在 jq 管道中间需要的标识运算符



我在 https://programminghistorian.org/en/lessons/json-and-jq 检查jq教程

它进行一些 json 重塑,从 json 文件中提取一些数据,在 https://programminghistorian.org/assets/jq_twitter.json

在某些时候,它会进行group_by,对同一用户的数据进行分组,提取一些用户数据并使用命令添加其相应的推文 ID

jq -s '. | group_by(.user) | .[] | {user_id: .[0].user.id, user_name: .[0].user.screen_name, user_followers: .[0].user.followers_count, tweet_ids: [.[].id]}' 

目前为止,一切都好。。。响应如下所示(仅提取一部分(:

{
"user_id": 18270633,
"user_name": "ahhthatswhy",
"user_followers": 559,
"tweet_ids": [
501064204661850100
]
}
{
"user_id": 27202261,
"user_name": "Dushan41",
"user_followers": 1201,
"tweet_ids": [
619172281751711700,
619172321564098600
]
}
{
"user_id": 2500422674,
"user_name": "pecanEgba74318",
"user_followers": 17,
"tweet_ids": [
619172331592773600
]
}

但是我想为所有具有多个tweet_ids的对象添加一个{"multiple_tweets":true}。

如果我像这样简单地管道,它工作正常:

jq -s '. | group_by(.user) | .[] | {user_id: .[0].user.id, user_name: .[0].user.screen_name, user_followers: .[0].user.followers_count, tweet_ids: [.[].id]} | (select(.tweet_ids | length > 1) .multiple_tweets = true)'

结果的一部分:

{
"user_id": 1653718716,
"user_name": "OAnnie8",
"user_followers": 315,
"tweet_ids": [
501064215160172540
]
}
{
"user_id": 356854246,
"user_name": "DrJLMooreIII",
"user_followers": 4888,
"tweet_ids": [
501064202904404000,
501064231387947000
],
"multiple_tweets": true
}
{
"user_id": 117155917,
"user_name": "rebekahwsm",
"user_followers": 5069,
"tweet_ids": [
501064233186893800
]
}

但是如果(无论出于何种原因,在这个例子中并不是真正需要的,实际上我这样做只是为了理解更新赋值(我想使用 |= 运算符,

jq -s '. | group_by(.user) | .[] | {user_id: .[0].user.id, user_name: .[0].user.screen_name, user_followers: .[0].user.followers_count, tweet_ids: [.[].id]} |= (select(.tweet_ids | length > 1) .multiple_tweets = true)'

我收到错误' jq:错误(在:30259(:结果为{"user_id":1330235048,"use...'

现在我真的无法理解的事情。如果不是直接使用运算符 |=,而是先通过身份运算符进行管道处理,则工作正常。 这种行为的原因是什么?为什么 |.|= 行为与 |= 不同 ?

为什么这会改变什么?

jq -s '. | group_by(.user) | .[] | {user_id: .[0].user.id, user_name: .[0].user.screen_name, user_followers: .[0].user.followers_count, tweet_ids: [.[].id]} | . |= (select(.tweet_ids | length > 1) .multiple_tweets = true)'

我想我仍然不明白 |= 运算符的真正工作原理。

谢谢你的帮助。

JQ 手册对这种行为的解释如下:

左侧可以是任何常规路径表达式;请参见path()

请注意,|=的左侧是指.中的值。因此$var.foo |= . + 1无法按预期工作($var.foo.中不是有效或有用的路径表达式(;请改用$var | .foo |= . + 1

由于底层内置(_modify(是使用setpathgetpathdelpaths实现的;|=的LHS必须是一个可以表示为数组的有效路径表达式;换句话说,path(LHS)不能失败。请参阅以下示例。

$ jq -n 'path(1)'
jq: error (at <unknown>): Invalid path expression with result 1
$ jq -n '1 |= . + 1'
jq: error (at <unknown>): Invalid path expression with result 1
$ jq -n '1 | path(.)'
[]
$ jq -n '1 | . |= . + 1'
2

最新更新