トピック

表計算ソフトの限界を超える巨大CSVファイル、テキストエディターで開いてみた

「巨大ファイルの快適操作」に情熱を燃やす、「EmEditor」の実力は?

EmEditorで巨大ファイルを開く

 テキストファイルの用途の一つとして、「データをとりあえずテキストファイルにしておく」というものがある。専用のバイナリファイルではなく、テキストファイルで保存すれば、幅広いソフトで扱えるため、潰しがきくというわけだ。

 そのため、ソフトが出力するログファイルや、ほかのソフトで読み込めるようにエクスポートしたファイルなどで、テキストファイルが使われることも多い。こういったファイルは、その性質上、GB単位など巨大になりがちだ。

 高機能かつ高速なWindows用テキストエディターとして「窓の杜」編集部でも愛用者が多い「EmEditor」の特徴の一つに、巨大ファイルに対応していることがある。16TBまでのファイルに対応し、読み込みや処理を高速に行える。さらに、16TB以上の巨大ファイルでも、その一部を読み込むことで、スムーズに編集できる「巨大ファイルコントローラー」の機能も備えている(「巨大ファイルコントローラー」は有償ライセンスのProfessional版のみ)。

 このことからサーバー管理者にも、巨大なファイルサイズになるサーバーログファイルを開いて確認し、検索する用途に「EmEditor」が使われているという。また、「EmEditor」のCSVモードを使って、Excelで読み込めないような巨大なCSVファイルからデータ分析するという用途でも使われていると聞く。

 そこでこの記事では、実際に巨大なファイルを「EmEditor」v24.1.1で開き、どのぐらい高速に、ストレスなく扱えるかを試してみた。


1.7GBのログファイルで検証行数は約2千万、表計算ソフトでは読み込み不可

 今回試す対象となるファイルは、本サイト「窓の杜」のWebサーバーのアクセスログを元にしたものだ。ただし、セキュリティとプライバシー上の理由から情報の一部を削除し、カンマ区切りのCSV形式に加工している。以下のような形式だ。

-,-,[20/Aug/2023:00:00:03+0900],"GET /docs/news/1524542.html HTTP/2.0",200
-,-,[20/Aug/2023:00:00:03+0900],"GET /library/software/screentogif/ HTTP/2.0",200
-,-,[20/Aug/2023:00:00:03+0900],"GET /css/wflib/article.css?17062901 HTTP/2.0",200
-,-,[20/Aug/2023:00:00:03+0900],"GET /css/wflib/color.css HTTP/2.0",200

 ファイルのサイズは1.7GBで、約2千万行ある。これだけ行数があるとExcelでは読み込めない。

Excelでは読み込めないサイズ

 このファイルをテキストエディターで開いて、ぱっと見たり、攻撃パターンの痕跡を思いついた点で検索したり、集計したりしてみる。

 検証マシンとしては、筆者がサブマシンとして使っているノートPC(ThinkPad E14 Gen 2)を利用した。4年前に発売された機種で、CPUはIntel Core i5-1135G7(4コア 8スレッド)、メモリは8GB、ストレージはSSDだ。

 このマシンで、「EmEditor」と、オープンソースのWindows用テキストエディター「Notepad++」とで巨大ファイルを開いてみる。なお、今回のファイルサイズは1.7GB。「巨大ファイル」としては小容量のため、巨大ファイルコントローラーは使用しない。

 「Notepad++」は主にプログラミングでよく使われているテキストエディターだ。今回は、「比較できる高機能を持っているが、特に巨大ファイル向けではないテキストエディター」として取り上げた。特殊な状況で比較させてもらったが、「Notepad++」ユーザーの方々にはご容赦いただきたい。

 そのほか、ログファイルの確認ということで、テキストエディターではないが、ログ検索などでよく使われるコマンドラインのテキスト検索ツール「GNU grep for Windows」でもいくつかの項目を試した。

 所要時間の計測は、OSのファイルキャッシュなどの影響を避けるために、毎回Windowsを再起動して対象のファイルをまだ触っていない状態から実行した。


大容量ファイルでは「ファイルを開く」速度差も大きい最短2.7秒、1.5倍の速度差あり

 まずは巨大ファイルを開くのにかかる時間だ。いずれも、テキストエディターを起動しておいてから、メニューから[ファイル]-[開く]で開いた。

 今回のファイルはCSV形式のため、「EmEditor」では自動的にCSVと自動検出されて、表として扱う前処理が加わる。そこで、設定でCSVの自動検出をOFFにした状態と、ONにした状態の両方を計測した。

 なお、「EmEditor」では開き終わったときにステータスバーに所要時間を含む情報が表示されるので、その値を採用した。一方の「Notepad++」では、ストップウォッチで計測した。

「EmEditor」(CSV自動検出OFF)で巨大ファイルを開いたところ
「EmEditor」(CSV自動検出ON)で巨大ファイルを開いたところ
「Notepad++」で巨大ファイルを開いたところ

 結果を見ると、「EmEditor」は、CSV自動検出オフで「Notepad++」の約1.5倍ほど高速に開いた。また、CSV自動検出をONにしても、「Notepad++」より速く開いた。

「EmEditor」(CSV自動検出OFF)2.693秒
「EmEditor」(CSV自動検出ON)3.515秒
「Notepad++」4.15秒


文字列検索の速度を比較 ~EmEditorが0.7秒、GNU grepが3.4秒~

 次に、文字列検索にかかる時間だ。それも、1件だけではなく合致する全件を一度に検索して件数を調べることにする。

 想定シナリオは、PHPへのアクセスを検索するというものだ。「窓の杜」のWebサーバーでは、PHPは使われていない。一方、脆弱性のあるWebサーバーを探すときに、とりあえずPHPのシステムでよくあるURLにアクセスしてみるという手法がある。そこで、アクセスログの中から「.php」を検索して、攻撃の可能性のあるアクセスを調べる、というわけだ。

 「EmEditor」では、検索ダイアログで文字列や検索を指定して、[次を検索]のかわりに[すべて選択]をクリックする。すると、テキストエディターのステータスバーに、件数や所要時間の情報が表示される。

「EmEditor」で文字列検索して件数を調べる

 「Notepad++」でも、検索ダイアログで文字列や検索を指定して、[次を検索]のかわりに[数える]をクリックする。すると、検索ダイアログのステータスバーに、件数が表示される。ここでも、所要時間はストップウォッチで計測した。

「Notepad++」で文字列検索して件数を調べる

 「GNU grep」は、PowerShellから実行した。grepに正規表現を無効にする「-F」オプションを指定し、コマンド全体を「Measure-Command { }」で囲むことで所要時間を計測した。

> Measure-Command { grep -F ".php" access_log.csv }
「GNU grep」で文字列検索して件数を調べる

 結果を見ると、「EmEditor」が圧倒的に速いという結果となった。

「EmEditor」0.656秒
「Notepad++」5.87秒
「GNU grep」3.352秒


驚くべき速さのインクリメンタルサーチ、(1.7GBのフィルタリングが)「キー入力よりちょっと遅い」レベル

 続いて、「EmEditor」のCSVモードとフィルター機能を使って、巨大ファイルから行を抽出してみる。

 今回のCSVファイルでは、5列目がHTTPのステータスコードとなっている。「200」が正常、「404」が該当するファイルがないという意味だ。

 ここでは、リクエストの形式がおかしいことを示す「400」を抽出してみる。リクエストの形式がおかしいということは、攻撃や、クライアントのミスなどが考えられる。

 フィルターツールバーで対象の列として5列目を指定する。そしてフィルターの文字列として「400」を入力する。このとき、1文字入力するごとに絞り込みを実行する「インクリメンタルサーチ」が有効になっていると、巨大なファイルでは文字の入力が重く感じることがあるので、フィルターツールバーの虫眼鏡アイコンから無効にするとよいだろう。なお、インクリメンタルサーチが有効になっている場合の絞り込み時間は、筆者の(さほど速くない)キー入力よりはちょっとだけ遅かったが、それに次ぐぐらいの時間で実行された。データ量を考えると驚くべき速さだろう。

 これで、5列目が「400」の、つまりHTTPのステータスコードが400となったリクエストが抽出された。

HTTPのステータスコードが400となったリクエストを抽出

 さらに「EmEditor」では、日時の範囲で検索やフィルターを実行することもできる。この機能を使って、日時の範囲を指定してフィルターを実行して、その範囲のログだけを抽出して絞り込んでみよう。

 今回のログは、3列目に次のような形式で日時が記録されている。「日/月/年:時:分:秒+0900」という形式だ。

[20/Aug/2023:00:00:02+0900]

 そこでまず、フィルターツールバーで対象の列として3列目を指定する。そして、フィルターツールバーの[[,]]ボタン(「数値範囲を使用する」)をクリックすると、数値範囲を入力するダイアログが開く。

 ここでまず、値の種類として[日付/時刻]を選び、[既定の日付形式を使用する]のチェックマークを外す。そしてテキストフィールドに、表記形式として「d/MMM/yyyy:HH:mm:ss」と入力する。すると、その下に「例」として、指定した形式で表記された日時の例が表示される。

 指定した表記形式のうち「MMM」は、省略された月の名前を意味している。ただし、そのままでは日本語での月の名前になるのに対し、今回のログでは「Aug」と英語表記になっているため、検索でマッチしない。そこで、右下の[ロケール]ボタンをクリックし、[ロケール](地域設定のこと)プルダウンリストで[英語 (米語) (en-US)]を選ぶ。

 形式を指定したら、ダイアログ上部の[最小値]と[最大値]に入力する。ここでは[最小値]に「21/Aug/2023:12:00:00」を、[最大値]に「21/Aug/2023:12:30:00」を入力してみる

 これで[OK]をクリックすると、指定した範囲の時刻のアクセスが抽出された。これについては、「操作したらすぐ終了」という感覚だ。

数値範囲を入力
ロケールを「英語 (米語) (en-US)」に
日時の範囲で絞り込み


巨大CSVでの列の追加や削除も超高速、2千万行を僅か数秒で処理

 CSVに変更を加える操作も試してみよう。

 CSVモードではExcelなどのスプレッドシートソフトと同じように、列単位での追加や削除ができる。これを巨大CSVファイルで実行してみる。

 なお、列の追加や削除は一見簡単な操作だが、約2千万行のテキストで実行すると、テキスト中の約2千万箇所という大きな変更になる。EmEditorでは変更ごとに、アンドゥ(元に戻す)ができるような情報を残しておくが、その情報もかなり大きくなり、処理負荷が高くなる。

 そこで、巨大CSVでの列の変更のような大きな変更については、アンドゥの情報を残さないように設定すれば、動作がだいぶ高速化される。それには、ツールバーの[カスタマイズ]ボタンか、メニューの[ツール]-[カスタマイズ]から、カスタマイズダイアログを開く。ここで[編集]ページから[常に長い元に戻す情報を破棄して速くする]にチェックマークを付ける。以下、この設定で試すことにする。

大きな変更でアンドゥのためのデータを残さない設定

 空の列を追加するには、追加したい場所の前または後の列を選択して、右クリックメニューで[右に列挿入]または[左に列挿入]を選ぶ。だいたいスプレッドシートと同じ操作だ。今回のデータで実行したところ、ステータスバーに表示された所要時間では3.4秒で追加された。

 同様に、列を削除するときには、削除したい列を選択して、Deleteキーを押すか、右クリックメニューで[列の削除]を選ぶ。こちらは、ステータスバーに表示された所要時間では5.9秒で削除された。

 約2千万箇所を一度に変更するという処理の量を考えると、かなり高速に追加や削除が実行されたことがわかる。

CSVに列を追加

 そのほかのCSV操作としては、隣りあった列の内容を結合して1つの列にする「列を結合」もできる。今回、1列目と2列目で実行したところ、5.4秒で実行された。

列を結合したところ

 面白い機能としては、選択した列のすべての行に同時に書き込むこともできる。列を選択した状態で、キーボードから文字を入力していくと、すべての行に同時にその文字が入力されていく。約2千万行あると、さすがにキーボード入力についてこれるわけではないが、同時に入力されるのは便利だ。

1列目に同時に書き込む

 こうしたCSVモードでの列単位の変更は、2023年11月公開のv23.0で性能強化されたものだ。EmEditorのCSVや巨大ファイルに対する力の入れようがうかがえる。


CSVの結合で情報を追加する

 最後に、「結合」つながりで、表の結合も試してみよう。リレーショナルデータベースでは、2つの表を、指定した列の内容が同じといった条件で1つに結合(JOIN)する機能がある。それと同じようなCSVの結合が、EmEditorのCSVモードでもできる。

 ここでは、CSVの結合を使って、ログのステータスコード列の右に、その説明を追加してみる。

 HTTPステータスコードとその説明を、以下のようなCSV形式で並べたファイルを用意する。

200,OK
301,Moved Permanently
404,Not Found

 ログのファイルと、このステータスコードのCSVファイルの両方をEmEditorで開いておく。そして、メニューで[CSV]-[高度]-[結合]を選ぶと、「CSVの結合」ダイアログボックスが開かれる。ここで、結合する文書として対象の2つのファイルをそれぞれ選び、Key列としてそれぞれのステータスコードの数値の列を指定する。このとき、結合後に入れる列を指定することもできる。

CSVの結合の指定

 そして、[今すぐ結合]から実行すると、結合された表が新しいドキュメントに現れた。今回のデータでは、実行時間は2.0秒程度だった。

CSVの結合により、ステータスコードの説明が追加された

 以上、「EmEditor」で巨大なテキストファイルを開いて、検索やデータ抽出を試した。

 ログファイルの巨大なテキストファイルは、専用のソフトを使ったり、コマンドラインのツールを使ったり、あるいはプログラムを組んだりして扱うことが多いだろう。しかし、いつものテキストエディターで高速に開けるなら、ぱっと目で見て様子をつかんだり、気になる点をアドホックにキーワード検索や抽出を実行して調べたりしやすい。

 さらに、CSVモードによって、Excelにも似た表形式で、Excelで読み込めないようなサイズのファイルを分析することもできる。

 もちろん「EmEditor」は、巨大ファイルやCSVファイル以外の機能も豊富であり、なおかつ軽快に動作する優れたテキストエディターだ。無償で使える「EmEditor Free」もあり、多くの機能が「EmEditor Free」でも使えるので、まずは試してみるとよいだろう。そして、そこで気にいって高度な機能を使ってみたくなった人は、ライセンスを購入することで「EmEditor Professional」にアップグレードできる。