我有一个 jq 问题。给定文件 file.json 包含:
[
{
"type": "A",
"name": "name 1",
"url": "http://domain.com/path/to/filenameA.zip"
},
{
"type": "B",
"name": "name 2",
"url": "http://domain.com/otherpath/to/filenameB.zip"
},
{
"type": "C",
"name": "name 3",
"url": "http://otherdomain.com/otherpath/to/filenameB.zip"
}
]
我希望使用 jq 创建另一个文件,只有当url的值与某个模式匹配时才会修改url。例如,我想更新与模式匹配的任何网址:
http://otherdomain.com.*filenameB.*
到某些固定字符串,例如:
http://yetanotherdomain.com/new/path/to/filenameC.tar.gz
生成的json:
[
{
"type": "A",
"name": "name 1",
"url": "http://domain.com/path/to/filenameA.zip"
},
{
"type": "B",
"name": "name 2",
"url": "http://domain.com/otherpath/to/filenameB.zip"
},
{
"type": "C",
"name": "name 3",
"url": "http://yetanotherdomain.com/new/path/to/filenameB.tar.gz"
}
]
即使能够找到网址,我也无法获得更多信息,更不用说更新网址了。这是我得到的(错误的结果,并没有帮助我解决更新问题):
% cat file.json | jq -r '.[] | select(.url | index("filenameB")).url'
http://domain.com/otherpath/to/filenameB.zip
http://otherdomain.com/otherpath/to/filenameB.zip
%
有关如何获取具有与正则表达式匹配的值的键的路径的任何想法?之后,如何使用一些新的字符串值更新密钥?如果有多个匹配项,则应使用相同的新值更新所有匹配项。
答案 0 :(得分:3)
好消息是,这个问题的解决方案很简单:
map( if .url | test("http://otherdomain.com.*filenameB.*")
then .url |= sub( "http://otherdomain.com.*filenameB.*";
"http://yetanotherdomain.com/new/path/to/filenameC.tar.gz")
else .
end)
不太好的消息是,除非你理解这里的关键聪明 - " | ="否则解释起来并不容易。过滤。有很多关于它的jq文档,所以我只是指出它类似于C系列编程语言中的+ =运算符族。
具体而言,.url |= sub(A;B)
与.url = (.url|sub(A;B))
类似。这就是更新如何完成"就地"。
答案 1 :(得分:1)
此解决方案使用 tostream 和选择标识网址成员的路径,然后使用 reduce 和 setpath更新值强>
WITH three_values(x) AS
(
VALUES
(NULL), (FALSE), (TRUE)
)
SELECT
a, b,
a = NULL AS a_equals_null, -- This is alwaus NULL
a IS NULL AS a_is_null, -- This is NEVER NULL
a OR b AS a_or_b, -- This is UNKNOWN if both are
a AND b AS a_and_b, -- This is UNKNOWN if any is
NOT a AS not_a, -- This is UNKNOWN if a is
(a OR b) AND NOT (a AND b) AS a_xor_b, -- Unknown when any is unknown
/* (a AND NOT b) OR (NOT a AND b) a_xor_b_v2, */
NOT a OR b AS a_implies_b -- Kleener and Priests logic
FROM
three_values AS x(a)
CROSS JOIN
three_values AS y(b);