【问题标题】:Use IFS$'\n' to read -r jq into multiple variables使用 IFS$'\n' 将 -r jq 读入多个变量
【发布时间】:2021-10-05 11:43:45
【问题描述】:

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

foo='
[{
    "name": "e2e (control-plane, true, true, true, ipv4, IPv4, true, false)",
    "failed_step": {
        "name": "Run Tests",
        "conclusion": "failure",
        "number": 11
    }
}, {
    "name": "e2e (control-plane, true, true, true, ipv4, IPv4, true, false)",
    "failed_step": {
        "name": "Generate Test Report",
        "conclusion": "failure",
        "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, true, true, true, ipv4, IPv4, true, false)
step = Run Tests
number = 11
job = e2e (control-plane, true, true, true, ipv4, IPv4, true, false)
step = Generate Test Report
number = 13

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

echo "$foo" | jq -r '.[] | .name, .failed_step.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, true, true, true, ipv4, IPv4, true, false)
step = 
number = 
job = Run Tests
step = 
number = 
job = 11
step = 
number = 
job = e2e (control-plane, true, true, true, ipv4, IPv4, true, false)
step = 
number = 
job = Generate Test Report
step = 
number = 
job = 13
step = 
number = 

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

【问题讨论】:

    标签: json bash while-loop jq ifs


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 肯定有几种解决方案可以解决 OP 的问题。但这可能是最有效的答案:)
    【解决方案2】:

    与其尝试使用\n,不如调整jq 以使用制表符分隔。比如:

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

    那你就可以while IFS=$'\t' read job step number; do ...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-09
      • 2017-02-11
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 2017-03-05
      相关资源
      最近更新 更多