pythonで UNIX コマンドの split もどき、お試し

UNIXライクな環境がない、という環境では、色々不自由なわけであり。だけれども Python だけはある、ということはないことはないと思う。多分貴方自身が「Pythonだけは入れさせてください」と動いたからだ。で、そんな環境でシェルコマンドのもどきを収集しておきたい、と前々から考えていた。

UNIX コマンドの split はファイルを分割するツールである。split の機能のうち、--bytesを頻繁に使う。行数での分割は一度も必要に感じたことはない。なぜなら、分割のニーズは、何かしらのバイナリファイル、多くはソフトウェアを、メールサーバのファイルサイズ制限などを回避するために発生するのであるし、分割して送らなければならないほど大きな「テキストファイル」はそもそも分割前に圧縮するであろう。

この split もどきを作ってみる。ただし、--bytesのみで、また、ファイル名の規則も別物。

 1 #! /usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 def _write(fn, outfn, sl):
 4     import mmap
 5     with open(fn, "r+b") as fi:
 6         mm = mmap.mmap(fi.fileno(), 0)
 7         with open(outfn, 'wb') as fo:
 8             fo.write(mm[sl])
 9         mm.close()
10 
11 if __name__ == '__main__':
12     import os
13     import sys
14     import argparse
15 
16     ap = argparse.ArgumentParser()
17     ap.add_argument("--bytes", type=int, default=100 * 1024**2)
18     ap.add_argument("inputfile")
19     args = ap.parse_args(sys.argv[1:])
20 
21     for i in range(0, os.stat(args.inputfile).st_size, args.bytes):
22         _write(args.inputfile,
23                '{}.{:03X}'.format(args.inputfile, i / args.bytes),
24                slice(i, i + args.bytes))

作ってはみたものの、遅い。Windows の MSYS は全般に I/O がなにやら遅いのであるが、MSYS に付属の split の倍の時間がかかっている。1.3GB を 100MB で分割するのに 1分40秒。MSYS split は同じ条件で 50秒。まぁ、実用時間だとは思うが、もう少しくらいは速い方がいいなぁ。

ところで「結合は?」。

必要にならないのよね、ほとんど。UNIX ライクな環境なら cat で済むし、7zip が相手の場合は、7zip が分割ファイルに直接対応しているし。cat もどきこそ簡単に書けるので、気が向いたら書くかもしれないです。気が向いたらね。