日本のインターネット草創期を知る方々と食事をすると、必ずといっていいほど話題になるのが「往時のネットニュース」。ネットニュースといってもスマートフォンに通知が届く昨今のものにあらず、「fj.*」などのニュースグループのことだ。"あの人"(お察しください)はどうしているかとか、きっかけはだいたい有名投稿者の消息だが、いまもLaTeXを使ってましてね、EmacsはCarbonを経てCocoaに辿り着きましたよ、などと当時の投稿内容に関連した近況報告へ話が変わることが常だ。
先日話題に上ったのは「スプレッドシート」。普通のMacユーザであればExcelかNumbers、Googleスプレッドシートあたりの話になるのだろうが、そこはそれUNIX系OS愛好者のことなので、CSVに変換してsedだawkだという内容になるのは仕方のないこと。
その流れで、CSVの内容をTerminalで確認するときどうしているかという話になったが、これは役に立った。CSVはスプレッドシートの内容をタブ(またはカンマ)区切りで書き出したプレインテキストだが、WEBやアプリでよく使うJSON形式に変換する中間素材として扱いやすく、いまも触れる機会が多いからだ。
CSVの内容をTerminalで見る……古色蒼然とした印象の字面だが、なかなかどうして、普遍的でありながら時代の変化もあるテーマといえる。今回は、その実用的な部分にスポットライトを当ててみよう。
columnコマンドを使う
CSVなどテキストファイルの内容確認はlessコマンドだけで済ませがちだが、テキストを複数列に整形する「column」コマンドを併用すると格段に見やすくなる。利用するcolumnコマンドのオプションは「t」(入力行のカラム数を自動判定)と「s」(区切り文字を指定)、結果は標準出力でlessなどのページャに渡せばいい。
表が大きい場合はただlesssに渡すだけではダメで、左右にスクロールして閲覧できるようにして(たとえば「-#2」)、行番号あり(-N)、折り返しなし(-S)もオプションに指定したほうがいい。これで、だいぶ体裁が表らしくなるはずだ。
しかし、この方法では空白セルが考慮されず、詰めて表示されてしまう。columnコマンドには、列数を決め打ちして表示する機能がないため、空白セルをそのまま(空けて)表示するには他の方法を考えるしかなさそうだ。
$ column -t -s"," train_fare.csv | less -#2 -N -S
エンコード形式を変換する
CSVの内容をTerminalで確認するとき、ときどき陥るのが"テキストエンコード形式の罠"。macOSのTerminalは、テキストエンコード形式の初期値がUTF-8であり、lessなどのコマンドもUTF-8環境下での利用を前提としている。
CSVはExcelなどスプレッドシートソフトで出力される都合上、Windows/macOSで利用されるためかシフトJISでエンコードされていることが多く、そのままTerminalで扱うことはできない。lessで見ようとしたとき「"○○○.csv" may be a binary file. See it anyway?」などと表示されたら、そのCSVはかなりの確率でシフトJISエンコードだ。
この問題は、macOSに標準装備の「iconv」コマンドで解決できる。使いかたはかんたん、「-f」オプションにSJIS、「-t」オプションにUTF8を指定し、引数としてCSVファイルを与え、適当なファイルにリダイレクトすればOK。ただし、改行コードが「CR+LF」の場合(Windowsで書き出されたCSVファイル)、rubyスクリプトにパイプして残滓の「^M」を取り除くこと。
$ iconv -f SJIS -t UTF8 train_fare.csv > temp.csv
$ cat temp.csv | ruby -Ku -pe 'gsub(/\r\n|\r/,"\n")' > UTF8.csv
最強のCSVビューア? 「tty-table」
先日のインターネット草創期を知る方との会食で教えていただいたのが、この「tty-table」。コマンドというより、サーバーサイドJavaScript環境のNode.js上で動作するパッケージ(ただしCUIを持つ)という位置付けだが、CSVの表示の忠実度という点では前述のcolumnコマンドを遙かに凌ぐ。空白セルの問題もない、満足度の高いCSVビューア(?)なのだ。
ただし、導入のハードルは少々高い。tty-table自体は「npm i -g tty-table」でインストールできるが、Node.js/npm環境を構築しなければならないため、事前にHomeBrewなどパッケージマネージャを導入しておく必要があるからだ。
Node.js導入の手順は端折らせていただくとして、tty-tableを導入してしまえばあとは快適そのもの。たとえば、カレントディレクトリに横スクロールが必要なほど大きいCSVファイルがあるとして、以下の要領でコマンドラインを実行すれば、満足の行く結果を得られるはずだ。
$ cat train_fare.csv | tty-table | less -#2 -N -S