[英]return specific items in json object using bash
I'm trying to take a json response (from a curl command and jq installed on my linux comp) with multiple objects, and edit each one with a for loop. 我试图对多个对象进行json响应(来自curl命令和安装在我的linux comp上的jq),并使用for循环编辑每个对象。 The problem is I don't understand how to take each {} and convert them into separate objects.
问题是我不明白如何将每个{}转换为单独的对象。 For example, my json response is:
例如,我的json响应是:
{
"Name": "testuser1",
"Username": "testuser1",
"Url": "www.test1.com"
}
{
"Name": "testuser2",
"Username": "testuser2",
"Url": "www.test2.com"
}
Ideally, I want to refer to each by a number. 理想情况下,我想用数字来指代每个人。 For example "echo $item | jq '.Name[0]'" for the
例如,“ echo $ item | jq'.Name [0]'”
{
"Name": "testuser1",
"Username": "testuser1",
"Url": "www.test1.com"
}
When I run the command above i get the following error. 当我运行上面的命令时,出现以下错误。
jq: error (at <stdin>:1): Cannot index string with number
I would like to run a forloop for each object. 我想为每个对象运行一个forloop。
You need to do two things: one, use the -s
option so that each separate object becomes an element of a single array. 您需要做两件事:一,使用
-s
选项,以便每个单独的对象成为单个数组的元素。 Two, you are trying to index the Name
, instead of accessing the Name
attribute of an array element. 第二,您尝试索引
Name
,而不是访问数组元素的Name
属性。
$ jq -sr '.[].Name' tmp.json
testuser1
testuser2
If you wanted to refer to a specific element of the stream, you could: 如果要引用流中的特定元素,则可以:
$ jq -sr '.[1].Name' tmp.json
testuser2
With that (and assuming none of your names will contain newlines), a proper loop would look like 这样(并假设您的名字中没有一个包含换行符),一个适当的循环将看起来像
while IFS= read -r name; do
...
done < <(jq -sr '.[].Name' tmp.json)
To select only the first name, you need to do the indexing before trying to go into the Name
element: 要仅选择名字,您需要在尝试进入
Name
元素之前进行索引:
jq -rs '.[0].Name'
By contrast, for a loop, the while read
approach given by @chepner's answer is indeed appropriate. 相比之下,对于循环而言, @ chepner的答案给出的
while read
方法确实是合适的。
jq is stream-oriented, so if you want to perform some operation on each object, then it might be sufficient to define that operation in jq, and let jq handle the stream without further ado. jq是面向流的,因此,如果要对每个对象执行某些操作,则在jq中定义该操作可能就足够了,让jq毫不费力地处理流。
If for some reason you need the index of each item in the stream, then you can avoid the -s
option if your jq has inputs
(as does jq 1.5). 如果由于某种原因您需要流中每个项目的索引,那么如果jq有
inputs
(与jq 1.5一样),则可以避免使用-s
选项。 (Avoiding the -s
option saves memory.) (避免使用
-s
选项可以节省内存。)
The following assumes that your jq does have inputs
; 以下假设您的jq确实有
inputs
; that indexing is 0-based; 索引是从0开始的; and that jq is invoked with the -n option.
并使用-n选项调用该jq。
foreach inputs as $input (-1; .+1; [., $input])
This will produce a stream of [INDEX, ITEM] arrays. 这将产生[INDEX,ITEM]数组流。 You can then tack on further jq filters using jq's pipe operator (
|
). 然后,您可以使用jq的管道运算符(
|
)进一步添加jq过滤器。
For the sake of illustrating a suitable method for invoking jq, let's suppose the stream of JSON entities comes from curl COMMAND
, and that we want the second item (that is, with index 1). 为了说明调用jq的合适方法,让我们假设JSON实体流来自
curl COMMAND
,并且我们想要第二项(即索引为1)。
curl COMMAND | jq --argjson i 1 -n -f program.jq
(Note the -n
command-line option!) (请注意
-n
命令行选项!)
def get($i):
label $done
| foreach inputs as $input (-1; .+1;
if $i == . then $input, break $done else empty end);
get($i)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.