web-dev-qa-db-ja.com

JQ json値から改行文字ではなく改行文字を印刷する方法

JSONで情報を出力するログがいくつかあります。これはelasticsearchへの収集用です。

一部のテスターや運用担当者は、サーバー上のログを読み取れるようにしたいと考えています。

JSONの例を以下に示します。

{
"@timestamp": "2015-09-22T10:54:35.449+02:00",
"@version": 1,
"HOSTNAME": "server1.example",
"level": "WARN",
"level_value": 30000,
"logger_name": "server1.example.adapter",
"message": "message"
"stack_trace": "ERROR LALALLA\nERROR INFO NANANAN\nSOME MORE ERROR INFO\nBABABABABABBA BABABABA ABABBABAA BABABABAB\n"
}

等々。

Jqに\ n文字の代わりに改行を印刷させることは可能ですか?

16
jjgong

最初に与えられた入力は、完全に有効なJSONではありません。目的の出力が何であるかは明確ではありませんが、以下が興味深いかもしれません。これは、jqの現在のバージョン(バージョン1.5)用に書かれていますが、jq 1.4に簡単に適合させることができます。

def json2qjson:
  def pp: if type == "string" then "\"\(.)\""  else . end;
  . as $in
  | foreach keys[] as $k (null; null; "\"\($k)\": \($in[$k] | pp)" ) ;


def data: {
  "@timestamp": "2015-09-22T10:54:35.449+02:00",
  "@version": 1,
  "HOSTNAME": "server1.example",
  "level": "WARN",
  "level_value": 30000,
  "logger_name": "server1.example.adapter",
  "message": "message",
  "stack_trace": "ERROR LALALLA\nERROR INFO NANANAN\nSOME MORE ERROR INFO\nBABABABABABBA BABABABA ABABBABAA BABABABAB\n"
};

data | json2qjson

出力:

$ jq -rnf json2qjson.jq
"@timestamp": "2015-09-22T10:54:35.449+02:00"
"@version": 1
"HOSTNAME": "server1.example"
"level": "WARN"
"level_value": 30000
"logger_name": "server1.example.adapter"
"message": "message"
"stack_trace": "ERROR LALALLA
ERROR INFO NANANAN
SOME MORE ERROR INFO
BABABABABABBA BABABABA ABABBABAA BABABABAB
"
3
peak

承知しました! -rオプションを使用すると、jqは文字列の内容をJSONエスケープ文字列としてではなく、端末に直接出力します。

jq -r '.stack_trace'
41
user3899165

jqonlyを使用する制約がない限り、jq出力をsed

cat the-input | jq . | sed 's/\\n/\n/g'

入力にもタブがある場合(JSONでは\t)、次のようになります。

cat the-input | jq . | sed 's/\\n/\n/g; s/\\t/\t/g'

これは、Javaスタックトレース行がstack_traceで始まるため、<tab>at<space>がJavaによって生成された場合(ログのソースが何であるかを知らなかった場合)に特に便利です。

警告:当然、これは正しいではありません。つまり、\\nを含むJSON入力は ""出力になりますが、 "n"出力になるはずです。正しくはありませんが、人間がデータを覗くには十分です。 sedパターンは、これを処理するようにさらに改善できます(読みやすさを犠牲にして)。

3
Piotr Findeisen