如何使用 jq 进行格式化打印?

Zet*_*tor 6 command-line bash printf text-formatting jq

jq具有将数字转换为字符串或连接字符串的内置功能。
如何在 jq 中格式化类似于printf填充(%4s)的字符串。

例如,如何强制 number 占用 10 个左对齐字符空间?
echo '{"title" : "A sample name", "number" : 1214}' | jq '(.title) + " " + (.number | tostring)'

dos*_*nak 21

jq可以使用引用字符串内的表达式\(foo)

字符串插值 -\(foo)

在字符串内部,您可以将表达式放在反斜杠后面的括号内。无论表达式返回什么,都将被插入到字符串中。

jq '"The input was \(.), which is one less than \(.+1)"' <<<  42
Run Code Online (Sandbox Code Playgroud)

结果:

"The input was 42, which is one less than 43"
Run Code Online (Sandbox Code Playgroud)


ibu*_*fen 5

jq没有printf。一种方法可能是;部分取自这里

echo '{"title" : "A sample name", "number" : 1214}' | 
jq '(.title) + " " + 
    (.number | tostring | (" " * (10 - length)) + .)'
Run Code Online (Sandbox Code Playgroud)

也许更好地添加为模块。


就我个人而言,我很快发现jq线条有些凌乱,如果做任何超出基础的事情,就会求助于 perl、python、php 或类似的东西。(但那是我:P)

例如使用 php:

echo '{"title" : "A sample name", "number" : 1214}' | 
jq '(.title) + " " + 
    (.number | tostring | (" " * (10 - length)) + .)'
Run Code Online (Sandbox Code Playgroud)

(当然也会添加错误检查等。)


Kus*_*nda 5

一种方法是不尝试在 中执行此操作jq,而是使用jq输出 shell 语句在 shell 中执行此操作:

eval "$(
    jq -r -n '
        { "title": "A sample name", "number": 1214 } |
        [ "printf", "%s %10s\\n", .title, .number ] | @sh'
)"
Run Code Online (Sandbox Code Playgroud)

或者,

eval "$(
    printf '%s\n' '{ "title": "A sample name", "number": 1214 }' |
    jq -r '[ "printf", "%s %10d\\n", .title, .number ] | @sh'
)"
Run Code Online (Sandbox Code Playgroud)

或者,

printf '%s\n' '{ "title": "A sample name", "number": 1214 }' |
{
    eval "$(
        jq -r '[ "printf", "%s %10s\\n", .title, .number ] | @sh'
    )"
}
Run Code Online (Sandbox Code Playgroud)

jq命令将输出

'printf' '%s %10d\n' 'A sample name' 1214
Run Code Online (Sandbox Code Playgroud)

使用@sh运算符安全地正确引用命令的每一位。评估时,这将输出

A sample name       1214
Run Code Online (Sandbox Code Playgroud)

类似的方法,但给你两个变量赋值:

A sample name       1214
Run Code Online (Sandbox Code Playgroud)

然后,您将在脚本中使用这些变量:

jq -r -n '
    { "title": "A sample name", "number": 1214 } |
    @sh "title=\(.title)",
    @sh "number=\(.number)"'
Run Code Online (Sandbox Code Playgroud)

对于已知数据很好的情况(例如,标题不能包含换行符),您可能会这样做

unset -v title number

eval "$(
    jq -r -n '
        { "title": "A sample name", "number": 1214 } |
        @sh "title=\(.title)",
        @sh "number=\(.number)"'
)"

printf '%s %10s\n' "$title" "$number"
Run Code Online (Sandbox Code Playgroud)

也就是说,确保数据被引用,然后将其传递给printfshell(这将调用外部实用程序printf,而不是内置的 shell)。

  • 请注意,“jq”以英文格式输出数字(例如,使用“.”作为十进制基数字符),而“printf”(对于那些接受“%d”浮点数的实现)期望以语言环境格式输出数字。一些“printf”实现,例如 zsh 或 ksh88/ksh93(在某些系统上称为“sh”)会将“%d”的参数解释为算术表达式,因此可以执行任意命令,因此清理很重要如果这些“.number”不能保证是数字,则输入。使用“%10s”而不是“%10d”可以避免该问题。 (4认同)