CSV形式のテキスト処理でawkの威力を思い知った!~ビギナーでもコンピュータの凄さを実感出来る言語

awk(オーク)について

UNIX系OSを使っている人なら多分知ってると思いますが、awkコマンドはテキスト処理に非常に強力な威力を発揮してくれる「いにしえの神アプリ」だと言い切っても良いと思います。このスクリプト言語は、CSVなどのデータベース的な構造を持つテキストデータの扱いに特化していると言うのは安直かも知れないですが、むしろそう言い切った方が、awkを知らない人にとってはわかりやすいだろうという話です。(実際の所はスペース区切りの情報も上手くセパレート出来てしまうから応用範囲は広いのですが)

CSV【Comma Separated Values】形式は、そのまんまカンマで区切られたカラムの概念を持つレコード形式です。Excel等の表計算と比べて言えば列の区切りをカンマで表したテキストデータです。これを見やすくするためにExcelにCSVをインポートしたり、CSVエディタを使用したりすると表として見えるので、見やすく、編集もしやすくなります。行についてはもちろんレコードを表すことになります。つまりこれはデータベースのテーブル(配列)と同じ概念です。

データベースについて

表計算はデータを整理するのに都合の良いツールなのですが、案外、Excelをデータベース・テーブル的に使う人は少ないのが実情です。どちらかというと汎用文書作成アプリとして「見た目(印刷結果)を重視した文書作成」が主で、セル間の値を使った計算でさえ機能を使っていない人が多くて驚いてしまいます。Excel方眼紙なんて言葉も有りますし・・

私としてはデータベース・テーブル的に整形された膨大なデータ処理こそExcelの真骨頂だと思っているのですが、使い方は人それぞれなので強要は出来ませんしするつもりもありません。でもExcelの能力と機能を活用せずに手間がかかる管理をしている人を見ると、もったいないなぁというのが本音です。

とても人間の手だけで管理出来ない程の多くのデータをExcelで効率よく処理出来る人は私の言いたい事を理解していただけると思います。膨大なCSV形式のデータでもExcel等の表計算ソフトで開けば加工したり集計したりもチョイチョイと楽勝になるのです。

Excelの弱点というか改善されない不具合というか

ところが、Excelには厄介なことがあります。まず数字を勝手に数値形式として読み込むので、例えば「0001」 という値は、勝手に「1」に置き換えられてしまいます。これが桁数にも意味のある例えば商品コードだったりすると桁数を合わせるために頭を0で揃えるのは普通にあることです。

この様な書式になっているCSVファイルをを明示的にテキスト形式だと認識させるためには、ファイルの拡張子.csvを一度.txtに変更して、Excelからウィザードを働かせながらファイルを開く必要があります。ファイルの種類をcsv、txtとして取り込み、形式をテキストとして指定してやらなくてはなりません。ExcelのCSVファイルの扱いについては実に面倒な仕様でありマイクロソフトには過去に何度か要望したのですが一向に改善される気配がありません。(その代わり要らない機能が実装されてゴテゴテの肥大状態が現状でしょう)

そもそもCSV形式はテキストファイルなのだから、数値として扱うのは仕様がマズイと思うのです。テキストとして開いてくれる仕様ならExcelに拡張子.csvを関連付ける意味はあるのですが、数字を数値として勝手な解釈をしてしまう時点で関連付ける意味は無いし、トラブルの元となるのです。(私の知る範囲では、Excel2013の以前では解決していないし改善する気配も全くなさそうです。きっと今後も改善されないでしょうね・・)

膨大なデータ処理はさすがに表計算では無理かな

次に問題となるのは読み込み可能な行数とカラム(列)数です。Excel2007以降で劇的に拡張されましたが、Excel2003では6万数千行以上は開けないという制限がありました。これ以上のレコード数を持つ情報を扱うとなると手っ取り早くAccessに頼る事になるのが実情ですが、Accessを持ってないとお手上げです。

ちなみにフリーの表計算アプリ(OpenOffice.org)も同じ制限を持っていたのですが、最新版(バージョンは失念)でこの制限が改善されより多くのデータを含むファイルを開けるようになりました。ただしOpenOffice.orgのCalcでは、数万行のCSVを読み込ませると行の高さ調整中のままフリーズするという不具合が起きます・・・つまり使えないのです。

そこで、Cassavaや、KutoCSVエディタなどのCSV専用エディタを引っ張りだして来て使って見るのですが、これまた数万行となると動作が緩慢どころか、フリーズ症状となり、快適な編集作業は望めないのです。これだけPCの性能が上がったにもかかわらず、たかだか50MB程度のテキストデータであるCSV形式のファイルを快適に編集できるGUIのソフトウェアがいまだに無いのです。

テキスト処理はテキストエディタに任せるべき?

CSVのデータ構造を理解している人ならば、テキストエディタ(秀丸エディタ、EmEditor、K2Editorなど)で処理した方が軽快でミスも少ないと知っていると思います。しかしテキストエディタで編集するには慣れが必要です。なぜこのご時世に、CSV形式のデータを表の体裁にして表示してテキストエディタの様に快適に編集するツールが出てこないのか?ニーズが無い?

※CSVモードを持つテキストエディタ(MIFES等)も存在します

いや、そんなことはないと思います。なぜならこの世にはネットショップがどんどん増えている実情、サイトの商品情報などの更新はCSVファイルで行っているケースがかなり多いはずなのです。おそらCSV編集ツールのニーズはあるけど良いツールが無いので結局ズルズルとその惰性で進んでいるんだと思います。

そこで一歩先を行ける人は、Excelを捨てて、MS-Accessや、FileMakerなどのデータベースアプリを使っての編集というのが現実的な話になります。実際Filemakerでショップデータを加工してアップロードしているという事例を結構耳にしましたし、私もAccessを使って商品データ(csv)を一気に編集するツールは日常的に使っていました。でも、わざわざCSVファイルをデータベースに取り込んで、内部的に加工(編集)してエクスポートしてサイトにアップロードするのはどうなんでしょう?csvデータはテキストデータです。この手間は実に無駄が多いと私は思うのです。

そこでawkの出番ですよね

そこでCSV編集の筆頭に上がってくるのがスクリプト言語「awk」です。スクリプト言語と言うからにはプログラミング言語の一種とも言えます。これを言うと眉を顰める人がほとんどでしょう。しかし私も非プログラマーですからしてそこは安心して欲しいのです。awkはプログラミングなんかわかんねーよって人でもその気さえあれば扱えるのです。「ちょっとの努力で覚えて後は楽をしたい」と言う気持ちを持っている私と同種の人ならば目的を達成出来るでしょう。私は先々凄く楽を出来るならちょっとした目先の努力は惜しみません。

awkにはカンマ区切りやスペース区切り等の、FS(フィールドセパレータ)に対応したデータ構造を持つテキストデータを効率良く処理する仕組みが組み込まれています。いや、むしろそういう用途の単に開発されたとしか思えないのです。CSVファイルの一括編集に最高のスクリプト言語だと私は思います。なにしろ私はプログラミングはまだまだ苦手です。だけどちょっと頑張った程度で単純なスクリプトを書ける程度のスキルです。シェルスクリプトやバッチファイルなんかは、やることをひとつずつ順番に記すだけで実行してくれるから大したスキルが要りません。

awkも手順を並べて記述していくだけで良いのであれば、十分対応できるのです。もちろんawkもれっきとしたプログラミング言語なので条件で分岐させてなんていう方法を使えば複雑な事も出来ます。でもそんなに難しい処理や複雑な事はさせなくても大抵のことは出来ます。単純な処理を行うスクリプトで処理して、処理した結果をまた別の単純な処理のスクリプトで加工します。

もちろん、これにはちょっとした数のデータなら手間かけた方がてっとり早いので無意味です。人間の手では到底扱え無い様な数のレコードを持つ情報なら、単純作業のスクリプトでも手間の分だけ分割すれば良いので意味が出てきます。実際、人力でやるなんてアホらしいからコンピュータを使うのです。

言い換えれば手作業で何度も繰り返しやってる事をawkでスクリプト化すれば良いのです。ちょっとした作業までスクリプト処理させる必要は無いと思いませんか?人間の手でちょいちょいと出来る事は手でやれば良いと思うのです。同じ作業を10万回とかアホらしくてやってられません。そういうのをスクリプトで処理するのです。

もちろん、より強力なPerlを理解している人はawkなんかに見向きする必要は無いでしょう。Perlの方が新しく洗練されていて柔軟だからです。だけどPerlの柔軟さが仇になる場合を想定できるでしょうか?私にはPerlは難しすぎて理解できないです。だけどawkならなんとかなります。ベタだろうが泥臭かろうが、バカにされようが、手作業で(バカみたいに)繰り返しやることを一つずつスクリプトに手順どおり記せば良いのです。目的を達成するの(結果こそ)が最優先だと思うのです。言語の理想とかそんなのはプログラマじゃない私には関係ありませんし。

続きを読む