分析と広告のためのCookie
分析と広告のためにCookieを使っており、どちらもGoogleに送られます。拒否しても、目に見える動作は何も変わりません。プライバシーポリシーを読む
ここで NDJSON を TSV に変換できます。無料、アカウント不要です。ファイルを上の枠に落とせば、数秒で結果がダウンロードできる状態になります。 変換はお使いのブラウザーの中で行われるので、ファイルはアップロードされません。Windows でも macOS でも Linux でも、iPhone でも Android でも同じように動き、通信を切っても動き続けます。
一度に100ファイルまで。フォーマットが混ざっていても構いません。
順番に変換し、まとめてZIPでダウンロードします。
NDJSON から TSV
アクセスログの 1 行を思い浮かべてください。クエリ文字列つきのパス、カンマだらけの User-Agent、値を引用したエラーメッセージ。これを CSV にすると、区切り文字であるカンマがほぼ全ての行の中に現れるため、大半のフィールドが引用符で囲まれます。
タブはログの値の中にほとんど登場しません。だから多くのフィールドが引用なしで書かれ、ファイルは列位置で読める状態を保ちます。ここから先は、この性質のありがたさと、それを一部の行だけ静かに崩す落とし穴の話です。
タブを含む値、ダブルクォートを含む値、改行を含む値は、CSV と同じ流儀で引用符に包まれます。それ以外——カンマを含む値も——はそのまま書かれます。これは IANA が定義するタブ区切り値の仕様(フィールド内のタブを禁止する)とは異なり、RFC 4180 の区切り文字をタブに置き換えたものです。
実務上の影響は、`cut -f4` や `awk -F$'\t'` がふだんは正しく動き、ログメッセージの中にたまたまタブが混ざった行だけ静かに壊れるということです。その行だけ列が一つ増え、それ以降の列がすべて一つずつずれます。エラーは出ません。貼り付けられた自由文が混ざる可能性があるなら、位置で読む前に検証するか、引用符を理解する読み込み方法を使ってください。
列は、ファイル全体で見つかったキーを、最初に登場した順に並べた集合です。これは 2 行目が 1 行目と同じキーを持つ保証がない NDJSON にとって正しい振る舞いですが、この変換を自動化する前に理解しておくべき、いちばん重要な点でもあります。
毎晩のエクスポートで、たまたま今日はエラーレコードが 12 行目に、翌日は 4 万行目に出てくると、2 つのファイルの列順は違ってしまいます。ヘッダー行はどちらも正しいので、名前で読むパイプラインは問題ありませんが、位置で読むパイプラインは翌日には壊れていて、それに気づく手がかりもありません。
対策は、ファイルに列順を決めさせないことです。変換の前に `jq -c '{ts, level, service, msg}'` のようにキーの集合を固定してしまえば、すべての行が同じ 4 つのキーを同じ順序で持つようになり、列順は一つに定まります。
これは幅広く疎な表になる問題も同時に解決します。混在したイベントをそのまま変換すると、どれかのイベント種別が一度でも持っていたフィールドの分だけ列が増え、ほとんどの行でそこが空になります。射影してから変換すれば、そのような無駄な列は生まれません。
`request` オブジェクトのメソッドとパス、`user` オブジェクトの識別子、`context` ブロックのトレース ID——それぞれの末端の値が `request.method`、`user.id`、`context.trace_id` のような列になります。
ドットを含む列名は `cut` や `awk` には無害ですが、SQL では引用が必要になり、多くの読み込みツールでは正しい識別子として扱えません。テーブルに入れる予定があるなら、あとから直すより `jq` の射影の段階で名前を付け替えておくほうが手間が少なく済みます。
PostgreSQL の `COPY` の既定は、引用符ではなくバックスラッシュによる独自のテキスト形式です。書き出されたファイルと辻褄を合わせるには `\copy events FROM 'out.tsv' WITH (FORMAT csv, DELIMITER E'\t', HEADER true)` のように、CSV 形式を明示してタブを区切り文字に指定します。
DuckDB は `read_csv('out.tsv', delim='\t', header=true)` で読み込め、型はサンプルから自動推定されます。これは便利であると同時に、先頭のゼロが消える識別子列の原因にもなるので、文字列として保ちたい列には明示的な型指定を渡してください。
JSON の null と空文字は、どちらもタブとタブの間に何もない状態になり、変換後は見分けがつきません。区切りテキストには、それを保持する第三の状態がないためです。
`user_id` が欠けていた件数を数えるのと、空文字だった件数を数えるのは違う質問ですが、この変換のあとではどちらも同じ答えになります。この区別が意味を持つなら、変換前に印を付けるか、null を型として保持できる Parquet を検討してください。
元のファイルは行ごとにキー名を繰り返しますが、TSV はヘッダーに一度だけ書いて値だけを並べるため、キーの種類が少ないレコードでは全体として文字量が減ります。逆に列の種類が多く値がまばらな表では、すべての行が使わない列の分のタブまで持つことになり、増える方向に働きます。
無料の上限は 1 ファイル 100 MB で、列を決めるためにファイル全体を読み込む必要があるため、実際に効いてくるのはこの上限よりメモリーの余裕のほうです。`split -l 500000` で安全に分割できますが、分けたファイルどうしは列順が食い違う可能性があるので、それも射影を先にやっておく理由になります。
表計算ソフトで開くだけなら、区切り文字を指定しなくても済む CSV や、識別子列を文字列のまま保てる XLSX のほうが適しています。データ基盤に入れて長く使うなら、型を持ち列順の問題も起きない Parquet のほうが有利です。
TSV が本領を発揮するのは、送り先がプログラムで、区切り文字で分割することが前提になっている場合だけです。「Excel で開きたいだけ」という目的なら、TSV を選ぶと 1 列にすべて詰め込まれた表になりがちです。
このタブの中で、プレーンな JavaScript が NDJSON を解析して TSV を書き出します。アップロードも、エンジンのダウンロードも、アカウントも、日ごとの上限もありません。
本番のイベントエクスポートには IP アドレス、セッション ID、リクエストパス、User-Agent が含まれます。それをホスト型の変換サービスに渡すことは、相手がどう約束していようと第三者へのデータ転送です。ここでは転送そのものが発生しません。
| NDJSON | TSV | |
|---|---|---|
| 正式名称 | Newline-Delimited JSON | Tab-Separated Values |
| 拡張子 | .ndjson, .jsonl | .tsv, .tab |
| メディアタイプ | application/x-ndjson | text/tab-separated-values |
| 最初の公開 | 2013 | 1993 |
| 仕様 | — | IANA text/tab-separated-values |
| ライセンス | オープン標準 | オープン標準 |
| 現在の位置づけ | 現行 | 現行 |
| ブラウザで開けるか | 対応なし | 対応なし |
| 代わりに検討される形式 | JSON, CSV | CSV, JSON |
pandasは NDJSON と TSV のどちらも読めるので、別のプログラムを開かずに、結果を元のファイルと並べて確かめられます。
TSV は 1993 年から使われています。規定は IANA text/tab-separated-values です。Microsoft Excel、LibreOffice Calc、pandasがこの形式を読めます。
TSV は 1993 年、NDJSON は 2013 年に登場しました。人に渡すならたいてい古いほうが安全で、新しいほうは同じ仕事をより少ないバイト数で片づけます。
いいえ。この変換は完全にブラウザーの中で行われるので、ファイルが端末から出ることはありません。ご自分で確かめられます。開発者ツールのネットワークタブを開いて、何か変換してみてください。ページそのものと、このサービスの費用をまかなっている分析・広告のリクエストは見えますが、あなたのファイルを運んでいるリクエストはひとつもありません。
はい。アカウントも透かしもなく、消費される 1 日の割り当てもありません。お使いの機械の上で動くので、何度でも戻ってきていただけます。ブラウザーが扱えるのは 100 MB までのファイルで、一度に 100 本です。
NDJSON と TSV は、内容の表し方が根本から違います。ですからこの変換は複製ではなく再構築です。誠実ではありますが、1 バイトも同じというわけではありません。 入れ子のオブジェクトは平らにされて列になります。深く入れ子になったデータは形を失います。
変換には要りません。すでに開いているブラウザーの中で行われます。そのあと結果を開くには、お使いの端末がふだん Tab-Separated Values を表示するのに使っているソフトが必要です。