
jq
数値を文字列に変換したり、文字列を連結したりする機能が組み込まれています。パディング(%4s)
と同様に、jqで文字列形式を指定する方法です。printf
たとえば、数字を左揃えにして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
1つのアプローチは、シェルでこれを行うのではなく、出力シェルステートメントをjq
使用してjq
シェルで実行することです。
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
同様のアプローチですが、値を割り当てることができる2つの変数を提供します。
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
つまり、データをシェルに渡す前に、データが引用されていることを確認してください。外部ユーティリティprintf
、組み込みシェルではありません)。
答え3
jq
を含めないでくださいprintf
。 1つのアプローチは次のとおりです。ここからインポートした部分:
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);
?>
(もちろんエラーチェックなども追加される予定です。)