ベンダー在庫CSVを前回のエクスポートと突き合わせる
サプライヤーが毎週新しい価格表を送ってきます。先週のファイルを左ペインに、今週のものを右に投入すると、SKU単位の価格変動がはっきり浮かび上がり、Excelで4,000行をスクロールしてどのセルが黄色くなったか探す必要がありません。Excelで2枚目のシートに対してVLOOKUPでやることもできますが遅いです。新しい価格をストアに反映する前のクイックなサニティチェックなら、diffの方が速いです。
2つのCSVファイルを貼り付けるかアップロードすると、変わった行・価格・フィールドを並べて表示します。ブラウザ内で動作、登録不要、アップロード不要。
2つのCSVファイルを比較するための、無料のブラウザ内ツールです。昨日のベンダー出力を左に、今日のものを右に貼り付けると、変わったセルが光ります。何もマシンの外には出ません。アカウントもアップロードもクォータもありません。
diff自体は文字レベルで、コンマ間にハイライトを散らさず、フィールド値の全体に寄せるためのセマンティック後処理を行います。このツールが想定する文法は事実上のCSV仕様 RFC 4180です。コンマ区切りフィールド、任意のダブルクォート、リテラルクォートをエスケープするためのクォート二重化、CRLFの行末。
8,000行のベンダー価格表を2つExcelで開き、価格が動いたSKUを探して列ごとにスクロールしてあきらめた経験があるなら、このツールは数秒でその変更まで連れて行ってくれます。自由形式の散文にはテキストdiffツールを使ってください。安定したキーを持つ構造化データなら、JSON diffがオブジェクトの並び替えをCSVよりはるかにうまく処理します。XML diffは古いERPからのレガシーなデータエクスポートに最適です。
比較は1行ずつ、文字単位を意識して行われます。挿入は右側に緑、削除は左側に赤で表示されます。行モードのパスは5MBのファイルでも合理的な性能を保ち、続いて変更行に対する文字モードの精緻化が、動いたフィールドそのものを浮かび上がらせます。たいていの表計算エクスポートでは、ターミナルでdiffを走らせるより速くて見やすいです。
誇張せずに言えば、これは行キーを認識する真の比較ではなく、テキストdiffです。別の列でソートして行を並べ替えると、内容が同じでもすべての行が変わって見えます。列を並べ替えても同じです。csvkitのcsvjoinやpandasのSKUに対するmergeのような主キーの概念はここにはありません。集合ベースの比較が本当に必要なら、貼り付ける前に両方のファイルを同じ方法でソートするか、それらのツールを使ってください。
ヘッダー行はこのツールにとってはデータです。1行目も他の行と同じように扱うため、ヘッダー名の変更は先頭の1行diffとして表示されます。スキーマドリフトをレビューするなら、たいていそれが望ましい挙動です。本体行だけ気にしたいなら、貼り付ける前に両側からヘッダーを取り除いてください。CSVフォーマット自体(ヘッダーの慣習を含む)はCSVに関する解説記事と、CSVリソース内のセル範囲を選択するURIフラグメントを定義するRFC 7111に説明があります。
テキストペインが2つ、diffが1つ。登録もアップロードもサーバーへの往復もありません。
古い方のCSVを左に、新しい方を右に貼り付けます。あるいはどちらかのアップロードをクリックして、.csv、.tsv、.txtファイルをディスクから直接読み込みます。サンプルボタンを押すと、両方のペインに小さな商品価格リストが入り、ツールの動きをまず確認できます。
Excelは.csvをWindowsでCRLF(\r\n)で保存します。Pythonのcsv.writerやUnixのシェルパイプラインなどはLF(\n)を書くことが多いです。一方がCRLF、もう一方がLFだと、すべての行が変わって見えます。貼り付ける前に同じエディタで両方を開く(またはdos2unixに通す)ことで改行を揃えてください。Excelで保存したCSVの先頭にあるUTF-8 BOMはもう一つの定番の犯人です。もう一方のファイルにBOMがないなら剥がしてください。
削除は左側に赤いハイライト、挿入は右側に緑のハイライトで表示されます。どちらかをスクロールするともう一方も追従します。変わった価格、末尾に追加された新しい行、リスト中ほどで修正されたメールアドレスを探してください。ヘッダーの変更は1行目に1行diffとして現れます。
サプライヤーが毎週新しい価格表を送ってきます。先週のファイルを左ペインに、今週のものを右に投入すると、SKU単位の価格変動がはっきり浮かび上がり、Excelで4,000行をスクロールしてどのセルが黄色くなったか探す必要がありません。Excelで2枚目のシートに対してVLOOKUPでやることもできますが遅いです。新しい価格をストアに反映する前のクイックなサニティチェックなら、diffの方が速いです。
顧客ダンプをパートナーに送る前にPIIをマスクします。メールは[email protected]に、電話はマスク、フルネームは頭文字に切り詰めます。ソースのエクスポートとマスク済みコピーをdiffし、変わったのはマスク対象列だけであることを確かめます。diffに思いがけずbilling_address列が現れたなら、マスクスクリプトはあるフィールドを取り逃がしています。ファイルがラップトップを離れる前に気づけます。
Google Merchant Center、Facebook Catalog、ほとんどのマーケットプレイスはCSV(あるいはTSV)フィードを食べます。CMSがフィードを再生成したあと、昨夜の確認済みコピーとdiffすれば、priceから末尾ゼロを取り去ってしまった正規表現、IF()のバグで全行の在庫列がin_stockからout_of_stockに変わってしまった事故、誰にも知らせず追加された新しいGTINフィールドを捉えられます。
営業オペレーションから「先週から変わった連絡先は?」と聞かれたら、同じレポートを2回(当時と今)エクスポートして2つのファイルをdiffします。CSVはデフォルトでレコードIDの順には並んでいないので、まずID列で両側をソートしてください。さもないと全行が並び替わって見えます。ソート後は、本物の変更(リードのステータスがMQLからSQLに動いた、バウンス後にメールが直された)がはっきり出ます。
夜間のETLジョブがS3にCSVを書き出します。今日の行数が昨日と妙に違います。両方を取得してdiffすると、スキーマドリフトが見つかります。上流APIがフィールドを追加したせいでテーブル中ほどに新しい列が現れ、下流のセルが1つずつずれていたわけです。diffは構造変化を一瞬で捉えます。行数チェックだけでは、何かおかしいと教えてくれるだけです。
データサイエンティストが実験結果のCSVを出してきます。手法を少し調整して再分析を回します。v1とv2をdiffしてください。テスト統計の列だけ変わったのか、それとも割り当て件数も動いた(コホート定義が動いた可能性あり)のか。分析結果を正直にdiffすることは、結果に基づいて機能をリリースする前の、最も安いサニティチェックです。
このツールがもっとも頻繁に表面化させるパース時のエッジケースの短いチートシートです。文法のリファレンスはRFC 4180と、実際のスプレッドシートツールが出力するもの。
| Topic | What this tool does |
|---|---|
| RFC 4180に従ったクォート | コンマ、ダブルクォート、改行を含むフィールドはダブルクォートで囲む必要があります。"Widget, small"は1つのフィールドです。4.99のようなプレーン値にクォートは不要です。RFC 4180を参照。 |
| エスケープしたダブルクォート | クォートで囲んだフィールド内のリテラルな"は二重化してエスケープします。"He said ""hi"""は値He said "hi"です。バックスラッシュエスケープは標準CSVではありません。一部ツールは受け付けますが。 |
| 埋め込まれた改行 | RFC 4180ではクォートで囲まれたフィールド内に改行が許されています。1つのセル内の複数行アドレスは妥当なCSVです。diffは各物理行を1単位として扱うため、改行を含むフィールドは折り返し行に変更が出ることがあります。 |
| 改行コード(CRLF対LF) | RFC 4180はCRLF(\r\n)を指定しています。ExcelはCRLFを出力します。多くのUnixツールはLFを出力します。左右のペインで両者を混在させるとすべての行が変わって見えます。比較する前に揃えてください。 |
| BOM(UTF-8) | Excelで保存したCSVはしばしばUTF-8 BOM(EF BB BF)で始まります。UnicodeのBOM FAQはUTF-8には任意かつ不要としています。2つのファイル間でBOMが食い違うと、1行目に幻のdiffが出ます。 |
| 区切り文字の方言 | カンマがデフォルト。多くのロケールでカンマが小数点なので、ヨーロッパ版Excelはセミコロン(;)でエクスポートします。TSV(タブ区切り)はよくあるバリアントです。TSVの背景を参照。意味のあるdiffには両方のファイルが同じ区切り文字を使う必要があります。 |
| ヘッダー行 | このツールは1行目をデータとして扱います。列名の変更は先頭の1行diffとして現れます。本体行だけを比較したいときは、貼り付ける前に両ペインからヘッダーを取り除いてください。Pythonのcsv.DictReaderやpandasのような多くのパーサーは慣習的に1行目をヘッダーとして扱いますが、ファイル形式自体はそれを要求しません。 |
| エンコーディング | ブラウザ内のFileReaderを通じてはUTF-8のみです。Latin-1(ISO-8859-1)やWindows-1252も読み込めますが、アクセント付き文字は化けます。iconvかVS Codeの「Save with Encoding」で変換してから貼り付けてください。 |
はい。エンジンは1行ずつ文字を比較するため、行や列を並べ替えると、内容が同じでも差分として表示されます。これはテキストdiffに、CSVを意識した読みやすさのための補助がいくつか加わったものです。行キーによるマッチング、列の並べ替え認識、型の意味的な理解はありません。そのレベルの比較が必要なら、csvkitのようなツール、主キーでmergeするpandas、あるいは両方のファイルをSQLiteに読み込んでEXCEPTクエリを走らせてください。日々のスプレッドシート比較なら、このツールがほぼカバーします。
ExcelはCSVをCRLF(\r\n)で書き、Pythonのcsv.writerは通常LF(\n)を書き、シェルパイプラインはフラグ次第でどちらにもなります。一方のペインがCRLFでもう一方がLFだと、diffはすべての行に差分を見ます。修正策は貼り付ける前に両側を揃えることです。同じエディタで開いて1つの改行コードで保存するか、片方をdos2unixかunix2dosに通します。RFC 4180はCRLFを義務づけていますが、現実のCSVファイルはどちらも使われています。
いいえ。これは1行ずつのテキストdiffです。1行目の列順が左でsku,name,price、右でname,sku,priceだと、diffは生のテキストしか見ないので、すべての行のすべてのセルが変わって見えます。両方のファイルを別々の列でソートしても同様です。比較する前に列と行を一致させて並べ替えるか、列モデルが本当に重要なときはcsvkitのcsvjoinやpandasのmergeのような行キーを認識するツールを使ってください。
Windows版のExcelはCSVの先頭にUTF-8のバイトオーダーマーク(バイト列EF BB BF)を書くことが多いです。ただしUnicodeのBOM FAQはUTF-8には不要だと述べています。一方のファイルにBOMがあって他方にない場合、1行目1桁目に1文字分の幻のdiffが出ます。きちんとしたテキストエディタ(VS Code、Notepad++、Sublime)でファイルを開いてBOMなしで保存し直すか、貼り付ける前に先頭の3バイトを手動で取り除いてください。
ここでFileReader経路が正しくデコードできるエンコーディングはUTF-8だけです。Latin-1やWindows-1252のファイルも読み込めますが、アクセント付き文字は化けて見えます(例:caféがcaféになる)。BOM付きUTF-16は完全に壊れて見えます。UTF-8でないファイルは先に変換してください。ターミナルならiconv -f WINDOWS-1252 -t UTF-8 input.csv > out.csv、VS Codeなら「Reopen with Encoding」してから「Save with Encoding」でUTF-8にします。Pythonのcsvモジュールもpandasも、読み込み時にソースのエンコーディングを指定できます。
数MBまでは快適で、瞬時に感じます。10MBを超えるとブラウザがそれを感じ始め、コストの大半は計算ではなく、ハイライト付きdiffのレンダリングです。非常に大きなエクスポート(50MB以上)の場合は、まず本当に気にする列や行に両方のファイルを絞り込んでください。csvkitのcsvcutやcsvgrep、JSONに変換したCSVに対するjq、手早いawk/grepなどはどれも前処理として有効です。それから絞り込んだ部分をここに貼り付けてください。
あなたのCSVがブラウザを離れることはありません。読み込み、diff、レンダリングはすべてあなたのマシン上、ローカルで動きます。入力に対する分析もログも、「親切な」クラウドへの往復もありません。確認したければ、DevToolsを開いてNetworkタブに切り替えて見てください。比較するときに外向きリクエストはありません。フォーマットの参照はRFC 4180、Pythonのcsvモジュールのドキュメントはパースのエッジケースを照らし合わせる際の参照です。