使用 IFS$'\n' 将 -r jq 读入多个变量

问题描述

我目前有以下代码可以按我的意愿工作。

foo='
[{
    "name": "e2e (control-plane,true,ipv4,IPv4,false)","Failed_step": {
        "name": "Run Tests","conclusion": "failure","number": 11
    }
},{
    "name": "e2e (control-plane,"Failed_step": {
        "name": "Generate Test Report","number": 13
    }
}]'

echo "$foo" | jq -r '.[] | .name,.Failed_step.name,.Failed_step.number' | while \
    read -r job && read -r step && read -r number; do
        echo "job = $job";
        echo "step = $step";
        echo "number = $number";
done

输出以下所需的输出

job = e2e (control-plane,false)
step = Run Tests
number = 11
job = e2e (control-plane,false)
step = Generate Test Report
number = 13

但是,我的问题是,有没有办法使用 IFS 来避免 3 个单独的读取语句?我想出了以下内容,但是,它生成输出不太正确。看起来它只读入第一个变量。

echo "$foo" | jq -r '.[] | .name,.Failed_step.number' | while IFS=$'\n' \
    read -r job step number; do 
        echo "job = $job";
        echo "step = $step"; 
        echo "number = $number"; 
done

输出

job = e2e (control-plane,false)
step = 
number = 
job = Run Tests
step = 
number = 
job = 11
step = 
number = 
job = e2e (control-plane,false)
step = 
number = 
job = Generate Test Report
step = 
number = 
job = 13
step = 
number = 

我觉得必须有办法做到这一点,但我已经尝试了一段时间,但没有成功。

解决方法

您不需要 while 循环。只需使用 jq 命令对其进行格式化:

echo "$foo" | jq -j '.[] | "job = ",.name,"\nstep = ",.failed_step.name,"\nnumber = ",.failed_step.number,"\n"'

这会产生您想要的相同输出:

$ echo "$foo" | jq -j '.[] | "job = ","\n"'
job = e2e (control-plane,true,ipv4,IPv4,false)
step = Run Tests
number = 11
job = e2e (control-plane,false)
step = Generate Test Report
number = 13
$
,

与其尝试使用 \n,不如调整 jq 以使用制表符分隔。类似的东西:

jq -r '.[] | .name + "\t" + .failed_step.name + "\t" + (.failed_step.number | tostring)'

然后你可以做while IFS=$'\t' read job step number; do ...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...