Pythonクックブック(2章)

ファイル操作の続き

特定ディレクトリの探索(glob)

globモジュールは、Unix 形式のパス名のパターン展開をしてくれるので、
下位ディレクトリを調べる必要がないような探索にはos.walk/fnmatchを使わなくてもよい。
globモジュール自体が、os.listdir()/fnmatch.fnmatch()を使っているからなのか。

[kobakoba0723@fedora13-intel64 ~]$ cat findgrepglob.py 
import os
import glob


def find_grep(search_dir, pattern='*'):
    for match in glob.glob(os.path.join(search_dir, pattern)):
        yield match
    # for search_dir in search_dirs.split(os.pathsep):
    #     for pattern in patterns.split(';'):
    #         for match in glob.glob(os.path.join(search_dir, pattern)):
    #             yield match


if __name__ == '__main__':
    import sys
    if len(sys.argv) != 3:
        print 'Usage: python %s <search_dirs> <patterns>' % (sys.argv[0], )
    for search_dir in sys.argv[1].split(os.pathsep):
        for pattern in sys.argv[2].split(';'):
            for file in find_grep(search_dir, pattern):
                print file
[kobakoba0723@fedora13-intel64 ~]$ python findgrepglob.py "$(echo $PATH)" '*.sh'
/usr/bin/gnome-power-bugreport.sh
/usr/bin/pm-utils-bugreport-info.sh
/usr/bin/amuFormat.sh
/usr/bin/pv.sh
/usr/bin/lprsetup.sh
/usr/bin/lesspipe.sh
/usr/bin/setup-nsssysinit.sh
/usr/bin/packagekit-bugreport.sh
/usr/bin/unix-lpr.sh
[kobakoba0723@fedora13-intel64 ~]$ 

findの検索対象に複数ディレクトリ指定できるってのがわかって嬉しかった。
nameオプションに複数のパターンを渡すことって出来ないんだろうか。

[kobakoba0723@fedora13-intel64 ~]$ find $(echo $PATH | sed 's/:/ /g') -type f -name "*.sh"
/usr/bin/gnome-power-bugreport.sh
/usr/bin/pm-utils-bugreport-info.sh
/usr/bin/amuFormat.sh
/usr/bin/pv.sh
/usr/bin/lprsetup.sh
/usr/bin/lesspipe.sh
/usr/bin/setup-nsssysinit.sh
/usr/bin/packagekit-bugreport.sh
/usr/bin/unix-lpr.sh
[kobakoba0723@fedora13-intel64 ~]$ 

2日前、Usageメッセージのモジュール名ハードコーディングしてるし。。。恥ずかし。
それと、which 相当のことをやる時に、$PATHの内容をソースにハードコーディングしてたけど、
osモジュールのenvironっていうディクショナリに'PATH'でアクセス(os.environ['PATH'])すれば良かったんだ。

その他(itertools)

itertoolsはイテレータを生成するモジュール。
itertools.zip()はイテレータブルオブジェクトを受け取って、リストのイテレータを返す。

>>> import itertools
>>> for elements in itertools.izip(['a', 'b', 'c', 'd'], ['a', 'b', 'e', 'd']):
...     print elements
... 
('a', 'a')
('b', 'b')
('c', 'e')
('d', 'd')
>>> for elements in itertools.izip_longest('spam', 'egg', 'snake'):
...     print elements
... 
('s', 'e', 's')
('p', 'g', 'n')
('a', 'g', 'a')
('m', None, 'k')
(None, None, 'e')
>>> 

その他(python以外)

昨日は、初めてソースにパッチを当てたり、srpmからrpmを作ったりしてみた。
LPIの試験でコマンドの使い方は知ってるつもりだったけど、いざやってみると出来ないもんだ。
実機上で始めて動いたら何ともいえず嬉しかった、しょうもないことしかやってないけど。

参考サイト

モジュールインデックス@Python 2.6.2 document
RPMバージョン4.8の機能と変更点@HDE コラム
ニュースレター20号@レッドハット

Python クックブック 第2版

Python クックブック 第2版