jq
具有将数字转换为字符串或连接字符串的内置功能。
如何格式化 jq 中的字符串,类似于printf
填充 (%4s)。
例如,如何强制数字左对齐占用 10 个字符空间?
echo '{"title" : "A sample name", "number" : 1214}' | jq '(.title) + " " + (.number | tostring)'
答案1
jq
可以使用引用字符串内的表达式\(foo)
在字符串内部,您可以将表达式放在反斜杠后面的括号内。无论表达式返回什么,都将被插入到字符串中。
jq '"The input was \(.), which is one less than \(.+1)"' <<< 42
结果:
"The input was 42, which is one less than 43"
答案2
一种方法是不尝试在 中执行此操作jq
,而是使用jq
输出 shell 语句来在 shell 中执行此操作:
eval "$(
jq -r -n '
{ "title": "A sample name", "number": 1214 } |
[ "printf", "%s %10s\\n", .title, .number ] | @sh'
)"
或者,
eval "$(
printf '%s\n' '{ "title": "A sample name", "number": 1214 }' |
jq -r '[ "printf", "%s %10d\\n", .title, .number ] | @sh'
)"
或者,
printf '%s\n' '{ "title": "A sample name", "number": 1214 }' |
{
eval "$(
jq -r '[ "printf", "%s %10s\\n", .title, .number ] | @sh'
)"
}
该jq
命令将输出
'printf' '%s %10d\n' 'A sample name' 1214
使用@sh
运算符安全地正确引用命令的每一位。评估时,这将输出
A sample name 1214
类似的方法,但给你两个变量赋值:
jq -r -n '
{ "title": "A sample name", "number": 1214 } |
@sh "title=\(.title)",
@sh "number=\(.number)"'
然后,您可以在脚本中使用这些变量:
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"
对于已知数据的情况好的(例如,标题不能包含换行符),您可以这样做
jq -r -n '
{ "title": "A sample name", "number": 1214 } |
[ .title, .number ] | @sh' |
xargs printf '%s %10s\n'
也就是说,确保数据被引用,然后将其传递printf
给 shell(这将调用外部的实用程序printf
,不是内置的 shell)。
答案3
jq
不具有printf
。一种方法可能是;部分取自这里:
echo '{"title" : "A sample name", "number" : 1214}' |
jq '(.title) + " " +
(.number | tostring | (" " * (10 - length)) + .)'
也许作为模块添加更好。
就我个人而言,我很快发现jq
代码行有些混乱,并求助于 perl、python、php 或类似的语言如果做任何超出基础的事情.(但那就是我:P)
例如,使用 php:
#! /usr/bin/env php
<?php
$data = json_decode(file_get_contents("php://stdin"));
printf("%s: %10d\n", $data->title, $data->number);
?>
(当然也会添加错误检查等。)