我有一个字符串时间戳键,我需要转换为数字,因为strftime
会抛出一个错误,它需要是一个数字。
journalctl -n1 --output=json | jq '.__REALTIME_TIMESTAMP | tonumber |= (. / 1000 | strftime("%Y-%m-%d")), .MESSAGE'
但我收到无效路径表达式错误。我想我的语法不正确。
__REALTIME_TIMESTAMP
我最终想以人类可读的格式和 key显示 key MESSAGE
。
我有一个字符串时间戳键,我需要转换为数字,因为strftime
会抛出一个错误,它需要是一个数字。
journalctl -n1 --output=json | jq '.__REALTIME_TIMESTAMP | tonumber |= (. / 1000 | strftime("%Y-%m-%d")), .MESSAGE'
但我收到无效路径表达式错误。我想我的语法不正确。
__REALTIME_TIMESTAMP
我最终想以人类可读的格式和 key显示 key MESSAGE
。
我有以下 json:
[
{
"_source": {
"layers": {
"http2": {
"http2.stream": {
"http2.length": "1030"
}
},
"http2": {
"http2.stream": {
"http2.length": "1246"
}
}
}
}
}
]
我正在执行以下jq
命令:
jq '.[]._source.layers.http2."http2.stream"' file.json
我期望得到以下结果:
{
"http2.length": "1030"
}
{
"http2.length": "1246"
}
但我只得到:
{
"http2.length": "1246"
}
输入
[
"8.1.1",
"7.4.33",
"7.4.5",
"8.2.6"
]
输出
{
"7": "7.4.33",
"7.4": "7.4.33",
"8": "8.2.6",
"8.1": "8.1.1",
"8.2": "8.2.6"
}
输出是一个对象,其中:
8
),值是该主要版本的最大版本7.4
),值是该主要/次要版本的最大版本经过大量的试验和错误,现在我只能提取专业并简化为数组。任何帮助深表感谢!
echo "[\"8.1.1\",\"7.4.33\",\"7.4.5\",\"8.2.6\"]" | jq -n 'reduce input[] as $version ({}; .[($version | split(".")[0])] += [$version])'
哪个输出:
{
"8": [
"8.1.1",
"8.2.6"
],
"7": [
"7.4.33",
"7.4.5"
]
}
编辑:作为参考并避免歧义,对于那些能够理解 PHP 的人来说,这是一个执行相同操作的 CLI 脚本:
#!/usr/bin/env php
<?php
array_shift($argv);
usort($argv, 'version_compare');
echo json_encode(
array_reduce(
array_reverse($argv),
function (array $prev, $version) use($argv) {
[$major, $minor] = explode('.', $version, 3);
$majors = array_filter($argv, function ($v) use ($major) {
return substr($v, 0, 1) === $major;
});
$minors = array_filter($argv, function ($v) use ($major, $minor) {
return substr($v, 0, 3) === "$major.$minor";
});
return $prev + [
$major => end($majors),
"$major.$minor" => end($minors),
];
},
[]
),
JSON_FORCE_OBJECT
);
让我们假设我有两个非常复杂的jq
表达式,但它们的不同之处仅在于一个返回另一个的补码,即它们之间的唯一区别是一个做select(expression)
而另一个做select(expression|not)
。
简化示例:
$ jq -n '$ARGS.positional[] | select( . > 2 )' --jsonargs 1 2 3 4 5
3
4
5
$ jq -n '$ARGS.positional[] | select( . > 2 | not )' --jsonargs 1 2 3 4 5
1
2
与其jq
在我的代码中重复这两个不同的表达式(实际上,每个表达式只有几行),不如将一个值传递到单个表达式中以在两种行为之间切换会很整洁。
我怎样才能做到这一点?
实际jq
代码(根据消息负载中编码的文件路径过滤 RabbitMQ 消息):
map(
# Add an array of pathnames that would match this message. This
# includes the pathnames of each parent directory, leading up to
# and including the pathname of the file itself.
.tmp_paths = [
# The full pathname is part of a base64-encodod JSON blob.
foreach (
.payload |
@base64d |
fromjson.filepath |
split("/")[]
) as $elem (
null;
. += $elem + "/";
.
)
] |
# The last element is the full file path and should not have a
# trailing slash.
.tmp_paths[-1] |= rtrimstr("/")
) |
[
# Match the pathnames given as positional command line arguments
# against the computed pathnames in the "tmp_paths" array in
# each message. Extract the messages with a match.
JOIN(
INDEX($ARGS.positional[]; .);
.[];
.tmp_paths[];
if (.[1:] | any) then
.[0]
else
empty
end
)
] |
# Deduplicate the extracted messages on the full pathname of the file.
# Then remove the "tmp_paths" array from each message and base64 encode
# them.
unique_by(.tmp_paths[-1])[] |
del(.tmp_paths) |
@base64
我假设我需要if
以某种方式修改该语句以使其提取或丢弃其文件路径与作为位置参数给出的路径名匹配的消息。
根据 JSON 规范,正斜杠不必用反斜杠转义,但可以。
我有一个 JSON 文件,其中出于兼容原因(但不在键内)转义了字符串值中的所有正斜杠:
{
"proto://some/path": "\/\/some\/path"
}
但是,jq
自动删除这些反斜杠:
$ echo '{"proto://some/path":"\/\/some\/path"}' | jq -c .
{"proto://some/path":"//some/path"}
我需要输出是{"proto://some/path":"\/\/some\/path"}
我怎么知道jq
不要更改任何字符串值并保留这些反斜杠?或者,有没有办法在它通过后将
这些反斜杠仅重新添加到值中jq
?
$ jq -c -n -e '[$x, $y]' --argjson x '"a"' --argjson y '"b"'
["a","b"]
我知道我可以做上面那样的事情。如果我想从 bash 数组生成一个 json 数组,如下所示。有没有办法使用任意长度的参数来做到这一点?
$ jq {some jq arguments} a b c # the bash array can be of an arbitrary length.
["a","b","c"]
注意 a、b、c 没有在命令行中引用,因为我希望输入简单。
我有以下 json 结构
[{"name":"SQS_URL","value":"xyz"}]
我想将其转换为这种结构
SQS_URL=XZY
JSON:
"{
"a": "https://is2-ssl.com/",
"b": "https://a5.-ssl.com/",
"type": "response",
"c": [
{
"Number": 1,
"Reportname": "XXX",
"size": "2.5",
"Variants": [
"YYY"
]
}
],
"Meta": "ABC"
}
所需输出:
XXX,a,https://is2-ssl.com/
XXX,b,https://a5.-ssl.com/
我想打印那些值包含“http”(url)的键值对,并将键和值与分隔符“,”合并,并将 ReportName 添加到它们
我有以下对象
{
"name": "Papanito",
"fields": [
{
"name": "Name1",
"value": "Value1",
"type": 0,
"linkedId": null
},
{
"name": "Name2",
"value": "Value2",
"type": 0,
"linkedId": null
},
{
"name": "Name3",
"value": "Value3",
"type": 0,
"linkedId": null
},
{
"name": "Name4",
"value": "Value3",
"type": 0,
"linkedId": null
}
],
}
我想在这个转换
{
"name": "Papanito",
"fields": [
"Name1": "Value1",
"Name2": "Value2",
"Name3": "Value3",
"Name4": "Value4",
],
}
我尝试了几件事,但我还没有弄清楚如何做到这一点。
{
"auths": {
"test": {
"auth": "testserfdddd"
}
}
}
{
"auths": {
"test": {
"auth": "testserfdddd"
},
"myrepo.com" {
"auth": "passworder"
}
}
}
作为命令行上的一个简单测试,我执行以下操作:
cat .docker/config.json | jq '.auths += {"myrepo.com": {"auth": "passworder"}}'
结果是我想要的
{
"auths": {
"test": {
"auth": "testserfdddd"
},
"repo.com": {
"auth": "test"
}
}
}
但是我希望通过 bash 脚本执行相同的逻辑。
REPO=repo.com
PASSWD=passworder
$JQ --arg repo "$REPO" --arg passwd "$PASSWD" '.auths.[$repo] += {"auth": $passwd}' .docker/config.json
但是,这会覆盖test.auth
torepo.com.auth
并且不会添加到auths
密钥
运行 bash 脚本时的结果提供以下结果
{
"auths": {
"repo.com": {
"auth": "passworder
}
}
}
前一个对象被完全覆盖。我需要在jq
表达式中适应的模式通常是什么?由于参数repo
是唯一的(test
与不同repo.com
),为什么该+=
操作在 bash 脚本中不起作用?