はじめに
phpによるgzファイルの検索スクリプトを作ったことがあるが、pythonの勉強と、両者の違いと良さを確認する為に以下要件のものを作ってみる
筆者はpython入門者,phpの経験少々
なぜスクリプトが必要なのか
linuxならgrep,windowsならfindコマンドがあるのではと言われそうですが、サーバー等の運用の仕事をしていると、容易に本番環境で抽出結果をファイル保存するのは危険なのと、自由に使えるサーバがなく支給されるのはwindowsPCだけというのが現状だったりします。
そこでwindows上でgzファイルのまま対象行を検索したり解析するためのスクリプトが役立つはずです(筆者は役立った)
php経験者がpython入門してはまったところ
- インデントが重要なこと
- 他のプログラム熟練者でさえインデントによるステートメントの管理をしていることが衝撃だと思うらしい
- タブインデントとスペースインデントが混ざってると怒られる
- if分などでelseの前が空行でelseだけにコードを書くと動かない
- 必ずコードが必要、何もしない場合はpassと記述する
if value == 'Python':
pass
else:
print('pythonじゃないよ')
- bool値をfalseという風に頭文字を小文字すると怒られる
- 本投稿とは関係ないが、falseとしたままでも怒られず、その行以降のステートメントが実行されないという事象があってなかなか気づけなかった。何故。 (centOS6.8 Python3.5)
要件
- windowsの環境(linuxでもたぶんうごくだろうけど)
- Python3をインストールした環境で実行
- コマンドラインオプションで対象ファイルを指定
- gzファイルのまま1行ずつ表示(判定・解析もやれたら)
コマンドラインオプションを利用する
ファイルの作成
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument("-f", "--file", dest="filename",help="入力ファイルを指定", metavar="FILE")
args = parser.parse_args()
print(vars(args)['filename'])
コマンドプロンプトで実行
C:\PythonScript>gzopen.py -f aa
aa
C:\PythonScript>gzopen.py -h
usage: gzopen.py [-h] [-f FILE]
Process some integers.
optional arguments:
-h, --help show this help message and exit
-f FILE, --file FILE 入力ファイルを指定
phpとの違い
phpの場合getoptという関数で-fという引数の後の引数が配列に格納される
$options = getopt("f:hp::");
ベストプラクティスを知らないまま使っているだけかもしれないが、pythonのargparseと違い、デフォルトの値やヘルプ機能がない。
pythonのargparseは、デフォルト値や、ヘルプ機能が最初から用意されており、-hでヘルプを表示できるのがとても良い(以前からやりたいと思っていた)
これは素晴らしい
gzファイルを1行ずつ読み込んで標準出力
ファイルの作成
import gzip
import codecs
filename = 'gzfile.gz'
zf = gzip.open(filename,'rb')
reader = codecs.getreader("utf-16-le")
contents = reader( zf )
for line in contents:
print(line)
phpとの違い
phpでは、下記のようなコードでgzファイルを1行ずつ取得でき、ただのテキストファイルでもそのまま処理可能。pythonではgzファイルのみのようだ。
$zh = gzopen($filename,"rb");
while (gzeof($zh) == false) {
$line = gzgets($zh);
}
コマンドラインオプションとgzファイルを1行ずつ読み込んで標準出力を両方行う
下記の例ではunicode(UTF-16LE)のテキストファイルをgz圧縮したものを利用している
ファイルの作成
import gzip
import codecs
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument("-f", "--file", dest="filename",help="入力ファイルを指定", metavar="FILE")
args = parser.parse_args()
filename = vars(args)['filename']
zf = gzip.open(filename,'rb')
reader = codecs.getreader("utf-16-le")
contents = reader(zf)
for line in contents:
print(line)
UTF-8版
zf = gzip.open(filename,'rb')
reader = codecs.getreader("utf-8")
contents = reader(zf) #encodings.utf_8.StreamReader
for line in contents:
print(line) #str
文字コードを気にしない書き方
zf = gzip.open(filename,'rt')
for line in zf:
print(line) #str
以下でもできるようだが、いまいちしっくりこない
zf = gzip.open(filename,'rt')
line = zf.readline()
print(line)
while line:
line = zf.readline()
print(line)
個人的課題
windows環境だと標準出力の文字コードがcp932だとかでpython上での
文字コードの扱い方を勉強しないといけなそう。理解が深まり次第記事をアップデートする予定