这是我输入的样子:
pollresp={
"ImportImageTasks": [
{
"Description": "SP",
"ImportTaskId": "import-ami-123456",
"Status": "deleted",
"StatusMessage": "User initiated task cancelation"
}
]
}
使用jq,我基于ImportTaskId过滤对象并打印Status和StatusMessage。
这是我的过滤器表达式的样子:
printf "%s\n%s\n%s" $(echo ${pollresp} | jq '.ImportImageTasks[] | select(.ImportTaskId=="import-ami-123456") | .ImportTaskId,.Status,.StatusMessage')
输出如下:
"import-ami-123456"
"deleted"
"Userinitiated
task
cancelation"
StatusMessage有空格。我试图保留空格并获得输出:
"import-ami-123456"
"deleted"
"User initiated task cancelation"
我该怎么做?
答案 0 :(得分:3)
默认情况下,Bash会在空格上拆分参数,因此回显的输出将在空格上进行拆分。
jq '.ImportImageTasks[] | select(.ImportTaskId=="import-ami-123456") | .ImportTaskId,.Status,.StatusMessage' <<< "$pollresp"
将输出:
"import-ami-123456"
"deleted"
"User initiated task cancelation"
答案 1 :(得分:2)
为了清晰和可读性而写,这可能看起来像:
#!/usr/bin/env bash
jq_script='
.ImportImageTasks[]
| select(.ImportTaskId=="import-ami-123456")
| [.ImportTaskId, .Status, .StatusMessage]
| @tsv
'
while IFS=$'\t' read -r importTaskId status statusMessage; do
printf '%s\n' "$importTaskId" "$status" "$statusMessage"
done < <(jq -r "$jq_script" <<<"$pollresp")
请注意@tsv
管道末尾的jq
- 生成制表符分隔的输出,while IFS=$'\t' read -r var1 var2 var3
循环 - 如BashFAQ #1中所述 - 迭代过来。
(如果在安全敏感的上下文中执行此操作,我建议修改您的jq
表达式以从内容字段中删除标签和换行符 - 或者,如果这些是合法数据,{ {3}}并剥离那些)。
答案 2 :(得分:1)
问题不在于jq
,而在于您使用bash子shell的方式。这是一个演示差异的脚本。
#!/bin/bash
pollresp='{
"ImportImageTasks": [
{
"Description": "SP",
"ImportTaskId": "import-ami-123456",
"Status": "deleted",
"StatusMessage": "User initiated task cancelation"
}
]
}'
filter='
.ImportImageTasks[]
| select(.ImportTaskId=="import-ami-123456")
| .ImportTaskId,.Status,.StatusMessage
'
echo _________________________ with printf "%s\n%s\n%s" unquoted subshell
printf "%s\n%s\n%s" $(echo ${pollresp} | jq "$filter")
echo
echo _________________________ with printf "%s\n" quoted subshell
printf "%s\n" "$(echo ${pollresp} | jq "$filter")"
echo _________________________ with no subshell
jq "$filter" <<< "$pollresp"
echo _________________________ with while/read
while read -r ImportTaskId
read -r Status
read -r StatusMessage
do
printf "%s\n%s\n%s\n" "$ImportTaskId" "$Status" "$StatusMessage"
done < <(jq "$filter" <<< "$pollresp")
echo _________________________
以下是显示差异的输出。如果你想在bash中进一步格式化或处理来自jq的结果,我会建议使用while / read方法。
_________________________ with printf %s\n%s\n%s unquoted subshell
"import-ami-123456"
"deleted"
"Userinitiated
task
cancelation"
_________________________ with printf %s\n quoted subshell
"import-ami-123456"
"deleted"
"User initiated task cancelation"
_________________________ with no subshell
"import-ami-123456"
"deleted"
"User initiated task cancelation"
_________________________ with while/read
"import-ami-123456"
"deleted"
"User initiated task cancelation"
_________________________
答案 3 :(得分:0)
请更正以下方法:
echo "$pollresp" | jq '.ImportImageTasks[] | select(.ImportTaskId=="import-ami-123456") | .ImportTaskId,.Status,.StatusMessage'
输出:
"import-ami-123456"
"deleted"
"User initiated task cancelation"