ディレクトリ以下のファイルすべてにもっと関数を適用する

前に書いた、ディレクトリ以下のファイルすべてに関数を適用するってやつを少し強化。

以下の機能を実装

  • 拡張子のカウント(countext)
  • atime, mtime, ctimeの表示(amctime)
  • サイズの取得(size)
  • wcコマンドの適用(wc)
  • statの適用(stat)
  • ファイル検索(find)
  • リストアップ(listing)

意外に使えたり。

import os

# basefunction to walking down directory tree with doing something.
# argument "func" is one argument function.
def walking(func, directory="."):
    nodes = []
    # generator is difficult.. I'm always confusing.
    directory = os.path.abspath(directory)
    for t in os.walk(directory):
        tree = t[0]
        nodes += [tree + os.sep + dirent for dirent in [x for x in t[2]]]
    for node in nodes:
        func(node)

# demos
def stat(dir="."):
    # don't work well
    def f(file):
        for line in os.popen("stat %s" % file).readlines():
            print line,
    walking(f, dir)

def countext(dir="."):
    dic = {}
    def f(file):
        ext = os.path.splitext(file)[1] # "python.txt" => ("python", ".txt")
        if ext in dic:
            dic[ext] += 1 
        else:
            dic[ext] = 1 # create new key
    walking(f, dir)
    dic.keys().sort()
    for n in dic.keys():
        print n + "\t%d" %dic[n]

def amctime(dir="."):
    import time
    from stat import ST_ATIME, ST_MTIME, ST_CTIME
    t = [ST_ATIME, ST_MTIME, ST_CTIME]
    def f(file):
        st = os.stat(file)
        atime, mtime, ctime = [time.ctime(st[x]) for x in t]
        print ",".join([file, atime, mtime, ctime])
    walking(f, dir)

def size(dir="."):
    from stat import ST_SIZE
    def f(file):
        print file, os.stat(file)[ST_SIZE]
    walking(f, dir)

def wc(dir="."):
    # binary depend function (you have to have "wc" command)
    def f(file):
        print os.popen("wc %s" % file).read(),
    walking(f, dir)

def find(dir="."):
    target = raw_input("target file:")
    def f(file):
        if target == os.path.basename(file):
            print file
    walking(f, dir)

def listing(dir="."):
    def f(file):
        print file
    walking(f, dir)

if __name__ == '__main__':
    import sys
    funcs = [["countext", "count number of each extension", countext],
             ["amctime", "display atime, mtime, ctime", amctime],
             ["size", "display size.", size],
             ["wc", "execute wordcounter command(wc)", wc],
             ["stat", "execute stat command", stat],
             ["find", "find file", find],
             ["listing", "list up files", listing],
             ]
    if len(sys.argv) == 1:
        print "usage : %s option dir"%(os.path.basename(sys.argv[0]))
        print "option list:"
        for n in funcs:
            print "\t%s\t%s" % (n[0], n[1])
        sys.exit()
    if len(sys.argv) == 2:
        target_dir = "."
    else:
        target_dir = sys.argv[2]
        if not os.path.exists(target_dir):
            print "%s: no such directory" % target_dir
            sys.exit()
    for f in funcs:
        if f[0] == sys.argv[1]:
            f[2](target_dir)
            sys.exit()
    print "unknown option \"%s\"." % sys.argv[1]