В этом случае у меня есть несколько файлов, таких как mem1.txt, mem2.txt и mem3.txt, как показано ниже, и я хочу извлечь из него последнее целое или десятичное число через Perl на машине с Linux.
$ cat mem1.txt
{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"__name__": "rbbn_pod_container_resource_limits",
"cluster": "blr-ocp1",
"container_name": "slb-container",
"k8s_pod_name": "sksbx2756x3-slb-57cf86b5-89lx9",
"service_name": "container-system-metrics"
},
"values": [
[
1676562016.975,
"8589934592"
]
]
}
]
}
}
$ cat mem2.txt
{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"__name__": "rbbn_pod_container_resource_limits",
"cluster": "blr-ocp1",
"container_name": "slb-container",
"k8s_pod_name": "sksbx2756x3-slb-57cf86b5-89lx9",
"service_name": "container-system-metrics"
},
"values": [
[
1676562016.975,
"1.02"
]
]
}
]
}
}
$ cat mem3.txt
{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"__name__": "rbbn_pod_container_resource_limits",
"cluster": "blr-ocp1",
"container_name": "slb-container",
"k8s_pod_name": "sksbx2756x3-slb-57cf86b5-89lx9",
"service_name": "container-system-metrics"
},
"values": [
[
1676562016.975,
"4"
]
]
}
]
}
}
Я бы ожидал результата, как показано ниже (значения без кавычек)
8589934592
1.02
4
Будет полезно, если я смогу извлечь все эти типы данных с помощью одной команды...
Используя perl по запросу, используя парсер JSON::XS c:
#!/usr/bin/perl
use strict; use warnings;
use feature qw/say/;
use File::Slurp;
use JSON::XS;
my @results;
sub fetch_value {
my $file = shift;
my $obj = read_file($file);
$obj = decode_json $obj;
return $obj->{"data"}{"result"}[0]{"values"}[0][1];
}
foreach my $i (1..3) {
push @results, fetch_value("file${i}.json");
}
say join "\n", @results;
8589934592
1.02
4
Вау, это работает именно так, как мне нужно. Большое спасибо.
Используя грон:
$ ls -1 file{1,2,3}.json;
file1.json
file2.json
file3.json
$ gron file1.json
json = {};
json.data = {};
json.data.result = [];
json.data.result[0] = {};
json.data.result[0].metric = {};
json.data.result[0].metric.__name__ = "rbbn_pod_container_resource_limits";
json.data.result[0].metric.cluster = "blr-ocp1";
json.data.result[0].metric.container_name = "slb-container";
json.data.result[0].metric.k8s_pod_name = "sksbx2756x3-slb-57cf86b5-89lx9";
json.data.result[0].metric.service_name = "container-system-metrics";
json.data.result[0].values = [];
json.data.result[0].values[0] = [];
json.data.result[0].values[0][0] = 1676562016.975;
json.data.result[0].values[0][1] = "8589934592";
json.data.resultType = "matrix";
json.status = "success";
$ for j in file{1,2,3}.json; do
gron "$j" |
awk -F' = ' '
$1 == "json.data.result[0].values[0][1]"{
gsub(/\042|;/, "")
print $2
}
'
done
8589934592
1.02
4
С jq:
$ jq -r '.data.result|.[0].values|.[0]|.[1]' file{1,2,3}.json
8589934592
1.02
4
Не perl
решение, но хороший пример того, насколько лаконичен jq при извлечении данных из файлов json.
$ jq '.data.result[].values[] | last | tonumber' mem*.txt
8589934592
1.02
4
for x in mem[123].txt; do
# Convert JSON to recode-oriented format
# Absense of -t option outputs every value as a string
# e.g. [0,"1",null,"\"2\""]
# => $[0] 0<0x0a>$[1] 1<0x0a>$[2] null<0x0a>$[3] \"2\"
# if -t was there then every string is quoted and others are not
# e.g. [0,"1",null,"\"2\""]
# => $[0] 0<0x0a>$[1] "1"<0x0a>$[2] null<0x0a>$[3] "\"2\""
# The -e option escapes impolite characters " ", ".", "\t"(<0x09>), "[", "]"
# in key to make the output unambiguous
parsrj.sh -e "$x" |
# Get last line
tail -n 1 |
# Since every output of parsrj.sh shall be formatted to:
# <key> <0x20> <value>
# separate a line with <0x20>, then get 2nd to last columns
# which is equivalent to <value>
cut -d ' ' -f 2-
done
Пожалуйста, опубликуйте действительный JSON.