答案1
使用jq
(不关心输入是紧凑形式还是多行形式):
your-command | jq -r '.[0].rows[0]._uuid[1]'
您的 JSON 文档是一个由对象组成的数组,您需要这些顶级对象中的第一个.[0]
.该对象包含一个rows
数组,并且您需要它的第一个元素.rows[0]
。该元素有另一个名为 的数组_uuid
,并且您需要该数组的第二个元素._uuid[1]
。
您-r
将得到解码后的“原始”数据。如果没有-r
,您将得到一个(带引号的)JSON 字符串。
从中获取数据的完全不同的方式特别的JSON 文档将是获取最后的值在文件中:
your-command | jq -r 'getpath([paths(scalars)][-1])'
首先使用 生成整个文档中每个标量值的所有“路径” paths
,并选出最后一个。然后,表达式使用最后一个标量的路径来getpath
提取最后一个值。对于给定的文档,这会产生预期的输出。
下面的代码可能做同样的事情,但是使用..
和with 显式递归select()
来提取所有标量值:
your-command | jq -r '[.. | select(scalars)][-1]'
就我个人而言,我会采纳这个答案中最重要的建议,因为它使用文档的结构,这必然在某种程度上对用户有意义。如果任何涉及的数组开始包含更多元素,则必须重新审视该代码,并重新表述问题。
答案2
如果我们可以确定有总是每行只有一个,
,并且您想要该行和其后的,
第一行之间的所有内容,您可以使用:]
sed
$ echo '[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]' | sed 's/.*,\([^]]*\)\].*/\1/'
"11111-222-33333-4444444"
或者,也避免引号:
$ echo '[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]' | sed 's/.*,"\([^]]*\)"\].*/\1/'
11111-222-33333-4444444
但是,由于这看起来像 JSON 数据,因此您不应该使用,sed
因为即使输入格式发生最小的更改,此解决方案也会中断。你应该使用专用的 JSON 解析器喜欢jq
代替。
答案3
如果您的有价值的数据仅包含数字和 -,您可以使用它。 (如果uuid长于23,没问题。)
echo '[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]' | sed -n "s/.*,\"\([0-9-]\{23,\}\)\"].*/\1/p"
输出:11111-222-33333-4444444
答案4
使用乐(以前称为 Perl_6)
~$ raku -MJSON::Tiny -e 'from-json($_)[0].<rows>[0].<_uuid>[1].put given slurp();' file
上面是用 Raku(Perl 编程语言家族的成员)编写的答案。关于命令行标志,调用raku --help
在 shell 命令行调用告诉我们:
该
-e
标志执行(以下)“单行”程序,其中strict
默认情况下启用。该
-M
标志在运行“one-liner”程序之前加载模块,在本例中是JSON::Tiny
。
输入示例:
[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]
示例输出:
11111-222-33333-4444444
根据模块主页(下面的第一个和第二个链接),“JSON::Tiny
实现了 RFC7159,它是 ECMA-404 的超集,因为它允许任何值作为顶级 JSON 字符串,而不仅仅是数组和对象。”from-json
OP 的输入可以使用和进行往返to-json
模块函数
请注意这个 Raku 答案,特别是[0].<rows>[0].<_uuid>[1]
结构的下降JSON
,与优秀的答案惊人相似第一的 jq
答案由@Kusalananda 发布。
https://raku.land/cpan:MORITZ/JSON::Tiny
https://github.com/moritz/json
https://raku.org