限りなき知の探訪

45年間、『知の探訪』を続けてきた。いま座っている『人類四千年の特等席』からの見晴らしをつづる。

百論簇出:(第277回目)『シニア・エンジニアのPython事始(その3)』

2023-10-15 08:43:18 | 日記
前回

現在、Pythonを使い始めて2月ほど経ち、いくつかのプログラムを作って使い勝手を調べている。簡単なデータ処理は、いつもならAWKでさっさと済ますしてしまうが、今は練習のためにわざわざPythonを使って書いている。たとえば、ウェブ上のデータの文字コードは現在では、たいていUTF-8であるが、私は長年Windowsを使っているので、Shift-JISの方が使いやすいし、蓄積したデータのほとんど全てがShift-JISだ。それで、現在でも、WebからダウンロードしたファイルはUTF-8からShift-JISに変換して格納している。この処理は、至って簡単な作業だ。たとえば、Pythonプログラムを一括してShift-JISに変換するにはわずか3ステップで完了する。

【ステップ1】Pythonファイルの名前をリストを作成する。
【ステップ2】リストに従って、.py ==> .org に名称変更する。
【ステップ3】同じリストを使い、UTF-8フォーマットの .org をShift-JISに変換して .py として同じ場所に格納する。

後ほど、詳しく説明するが、このような作業はいつも、都度、AWKで書いて処理しているが、ものの数分で完了する。今回、Pythonで書いてみたが、文法エラーや、関数の引数などを調べていて、結局、1時間もかかってしまった。仕事の効率からいえば、断然AWKの方が早いのだが、遅れた理由は私がPythonに未熟なせいだけでもない。時間がかかった理由は、Pythonはあまりにも汎用なので、今回のような単純作業では本来の仕事にとりかかるまでの準備で時間(プログラムコード作成時間)がかかってしまうのだ。

その理由を、具体的に説明しよう。

まず、Pythonファイルのリストは次のようなものだ。[py.lst]
 1: d10.py                       726 2023-09-XX 09:14:27  637
 2: d6.py                        456 2023-09-XX 14:04:06  555
 3: d7.py                       1113 2023-09-XX 14:15:22  824
 4: d8.py                       1412 2023-09-XX 14:27:57  275
 5: d9.py                        892 2023-09-XX 12:33:27  687
 6: exe_expandf.py              1096 2023-09-XX 14:22:08  854
 7: exe_expandf0.py              722 2023-09-XX 11:18:37  481
 8: exe_pdf2txt.py              1862 2023-08-XX 18:50:13  108
 9: expand.py                    913 2023-09-XX 14:03:24  857
10: fnexpdf.py                   456 2023-09-XX 22:04:06  555

処理は、このリストを読み込み .py ==> .org にrename する。まず、AWKプログラムをお見せしよう。
{
# jgawk -f cnv_fname.awk py.lst

  if(length($0) ==0 ) exit;

  split($1, aa, ":"); 
  ff = $2
  fforg = sprintf("%s%s", aa[2], $2);
  gsub(/\.py/, ".org", fforg);

  printf("ren %s %s\n", ff, fforg);
}

わずか数行で、処理が終わる。これに対して、Pythonファイルは40行も必要だ!(もっとも、もう少し工夫すれば、30行程度にはなるだろうが。。。)--
# -*- coding: Shift-JIS -*-
## py cnv_fname.py py.lst

import os, sys, re

end_flag = False;

def main():
  global end_flag;

  args = sys.argv;
  xx1 = len(args);

  fin_fname = args[1]
  fin = open(fin_fname, 'rt');

  while end_flag == False:
    sstxt = fin.readline();
    do_cnv_sjis(sstxt);

def do_cnv_sjis(sstxt):
  global end_flag;

  xlen = len(sstxt);
  if xlen <= 1:
    end_flag = True;
  else:
    ss2 = sstxt.split(':');

    dirx = str(ss2[1]);
    dirx2 = re.sub(' ', '', dirx);
    dirx3 = dirx2.split('.py');
    orgff = dirx3[0] + ".org";
    ff = dirx3[0] + ".py";

    print("copy %s %s"  %(ff, orgff));

if __name__== "__main__":
 main();

このように、2つのプログラミング言語で同じ処理を行うとそれぞれの言語の適/不適が明瞭に分かる。
AWKは与えられたデータファイルを一行ずつ読み込むことを想定している。それで、何も指示しなくてもファイル名が与えられると、自動的にファイルをオープンし、一行毎、読み込んで、その内容を与えてくれる。くれる。また、仕切り文字(デフォルトで空白)毎に$1、$2、$3などの名称で、データが保管される。これに対してPythonでは、これら全てのことを自分のコードで明示的に行わないといけない。これがPythonの処理では、40行ものコードが必要な理由だ。UTFからShift-JISの変換は前回も出てきたrtfconv.com を使う。

rtfconv.com -h -cUTF8 -cJ -mK -mU utf.file > shift_jis.file

結局、AWKはテキスト文の簡単な変換目的では、Python(や、BASIC、C言語など)より遥かに簡便であることが実証された。

残念なことに、このような便利なソフトウェアのAWKを現在では、ソフト開発者ですらを知らない。それもそのはずで、大型の本屋に行ってもAWK関連の本を見つけることができないからだ。私が思うに、AWKが廃れた一つの理由は、AWKが扱う文字コードが基本的にASCII(Shift-JIS)であるため、現在主流となったUTF-8 やダブルバイト文字のハンドリングがうまく行っていないことが挙げられる。確かに、UTF-8は jgawk -W ctype=UTF8 ....と書けば扱うことはできるが、データファイルの先頭にBOMマークが入っているとエラーとなる。

また、日本語を扱える gawk は、2009年9月の3.1.7が最新バージョンであるが、match() 関数では、ローマ字の大文字と小文字を区別できない場合がある。また、2バイト文字と1バイト文字をどちらも同じ1文字と換算する。つまり、バイト数ではないのだ。

このように、AWKにはいろいろな欠点はあるものの、簡単な処理を簡単に書けるという、他のプログラムでは得難いメリットがあることは特筆すべき長所だ。この一事の利点だけでも、私は、今後とも(多分死ぬまで)AWKを使い続けていくになると思っている。

続く。。。
コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 智嚢聚銘:(第40回目)『中... | トップ | 智嚢聚銘:(第41回目)『中... »
最新の画像もっと見る

コメントを投稿

日記」カテゴリの最新記事