我在 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
(是使用setpath
、getpath
和delpaths
实现的;|=
的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