ファイル操作

perlでfile.txtというファイルを開くときはopenという関数を使って、

open(FILE, 'file.txt') or die "$!";

のようにすれば良いみたい。開くことができなかったときはエラーメッセージを出して
終了するようにしている。
openの最初の引数はファイルハンドルでファイルを開いた後の操作は
ファイルハンドルを通じて行うみたい。
pythonでもやはりopen関数を使って、

f = open("file.txt", "r")

とすれば良いみたい。第二引数のrは読み込み専用で開くということ。
pythonのopen関数はファイルオブジェクトを返すので、
ここではfに代入している。
開いた後の操作はこのファイルオブジェクトのメソッドを使って行うようなので、
perlのファイルハンドルに当たると考えればよいのかな。
ファイルを閉じるときはperlではclose関数にファイルハンドルを指定して、

close(FILE);

とすればよいみたい。
pythonではファイルオブジェクトのcloseメソッドで

f.close()

のようにすれば良いみたい。
openとcloseの間でファイルの処理を行うことになるわけで、
例えばpython

f.read()

とすると、ファイル全体を1つの文字列で返してくる。
ファイルをテキストファイルではなく、バイナリファイルとして扱うときは
perlの場合はbinmode関数を呼び出す必要があるみたい。
引数にはファイルハンドルを与えてbinmode(FILE)のように使うみたい。
pythonの場合はopen関数のモードを指定する引数でバイナリモードを指定できて、
バイナリモードで読み込むときは、

f = open("data.bin", "rb")

のようにすれば良いみたい。
csvファイルを扱うときはpythonではcsvモジュールを使うと良いみたい。
例えば以下のような内容のファイル(data.txt)があって、

Hanako, 65, 90, 100, 80, 73
Ichiro, 8, 7, 23, 21, 24
Jiro, 74, 31, 41, 59, 38
Taro, 100, 95, 98, 82, 61
Hiroko, 55, 48, 79, 90, 88
Saburo, 74, 41, 59, 31, 38

各人の数値を合計して名前の隣に表示するスクリプトを以下のように
書いてみた。

import csv
csvfile = "data.txt"    
reader = csv.reader(file(csvfile, "rb"))  #csvファイルの読み込みにはcsv.readerオブジェクトを使うみたい。
for row in reader:  #rowは各人の名前と数値の文字列を要素として持つリストになる。
    score = row[1:] #数値の文字列のみを持つリストをつくる。
    sum = 0
    int_score_list = []
    for i in score: #数値の文字列を数値化してリストにする。
        int_score = int(i)
        int_score_list.append(int_score)
    for s in int_score_list: #合計値を計算
        sum = sum + s
    print row[0],sum

実行結果は以下の通り。

Hanako 408
Ichiro 83
Jiro 243
Taro 436
Hiroko 360
Saburo 243

次にカレントディレクトリ内のファイルの名前の一覧を表示する
プログラムを書いてみる。
pythonではosモジュールの引数に与えたファイルやディレクトリのリストを返すlistdirという関数を使って、
引数にカレントディレクトリの名前を与えればよいみたい。
カレントディレクトリはやはりosモジュールのgetcwdという関数で取得できるみたいだから、
以下のように書けた。

import os
dirname = os.getcwd()
files = os.listdir(dirname)
for file in files:
    print file

pathが存在するかどうか調べるときはpythonではosモジュールのexistsという関数を使って、

import os
os.path.exists(path)

とする。pathが存在すればTrueが、存在しなければFalseが返ってくる。
ファイルpathのサイズをバイト数で得るには、

import os
os.path.getsize(path)

とすれば良いみたい。
カレントディレクトリ中の拡張子が.txtのファイルの一覧を取得するには,
該当ファイル名をリストにして返す
globモジュールのglob関数を使うと便利みたいで、

import glob
glob.glob("*.txt")

のように使うみたい。
この他、ファイルpathを削除するときはremove関数、ディレクトリpathの削除にはrmdir関数、
ファイル名またはディレクトリ名の変更にはrename関数を以下のように使えばよいみたい。

import os
os.remove(path)
os.rmdir(path)
os.rename(変更前のpath, 変更後のpath)

さて次は問題に取り組んでみる。
mmlog.txtというファイルの内容は以下のようになっている。

No.0010  615
No.0009  602
No.0008  569
No.0007  549
No.0006  535
No.0005  514
No.0004   23
No.0003   19
No.0002   10
No.0001    4
No.0000    1

このファイルを元にNo.が1つ増えるごとに右の数値がどれだけ増加したかを
表示するプログラムを以下のように書いてみた。

f = open("mmlog.txt", "r")  #ファイルを読み込みモードで開いて
content = f.readlines()   #ファイルの各行をリストに読み込む
f.close()
blist = []
for i in content:
    s_content = i.split()  #ファイルの各行をNo.と数値の部分に分けて
    busuu = int(s_content[1]) #数値の部分を文字列から数値化する
    blist.append(busuu) #数値の入ったリストを作成
n = range(0, 10)
n.reverse()       #9〜0のリストを作成
n2 = range(1, 11)
n2.reverse()       #10〜1のリストを作成
for y in range(0,10):  #出力する表を作成
    print "No.%04d => No.%04d: %d" %(n[y], n2[y], blist[y]-blist[y+1])

実行結果は以下の通り。

No.0009 => No.0010: 13
No.0008 => No.0009: 33
No.0007 => No.0008: 20
No.0006 => No.0007: 14
No.0005 => No.0006: 21
No.0004 => No.0005: 491
No.0003 => No.0004: 4
No.0002 => No.0003: 9
No.0001 => No.0002: 6
No.0000 => No.0001: 3

次にカレントディレクトリの拡張子が.txtであるファイルすべてについて、そのファイルが、
・更新されて1日以内(day)
・更新されて1週間以内(week)
・更新されて1週間より多く経過(old)
のいずれかに当てはまるか調べて表示するプログラムを書いてみた。
スクリプトは以下の通り。

import os
import glob
import time
cdir = os.getcwd() #カレントディレクトリを取得
files = glob.glob("*.txt") #カレントディレクトリ内の拡張子が.txtのすべてのファイルを取得
filenames = [os.path.join(cdir,file) for file in files] #該当ファイルの絶対パスを取得
for absfile in filenames:
    renewtime = os.path.getmtime(absfile) #該当ファイルの最終更新時刻を取得
    if renewtime >= time.time() - 60*60*24:
        print "(day)  %s" %absfile.split("\\")[-1] #更新が1日以内のものを表示
    elif time.time() - 60*60*24 > renewtime >= time.time() - 60*60*24*7:
        print "(week) %s" %absfile.split("\\")[-1] #更新が1週間以内のものを表示
    else:
        print "(old)  %s" %absfile.split("\\")[-1] #更新が1週間より前のものを表示

実行結果は以下の通り。

(day)  data.txt
(old)  memo.txt
(week) mmlog.txt
(week) monndai7_4.txt
(old)  newfile.txt
(old)  test.txt
(old)  test2.txt