ワカメの育て方

mscファイル内容列挙の作り方。

いや、別に何かのためになるとかじゃないし、「ざっつゴミ作業」なんで本来ひとにみせられるシロモノじゃないんだけれど、単に作業記録を「捨てたい」ので書き残すだけ。似た作業、どうせ何度もするけど、そのたびに自分のPCの発掘作業すんのダルいし。

作業その壱。mscファイルを探す。これは単に MSYS の find で。

1 me@host: ~$ find /c/Windows -iname '*.msc' | tee /c/Users/hhsprings/msc.log

当然「ずんげー時間がかかります」。そして、だからこそ「findでやっちめぇ」。この種の作業をするときは、「完成品を作る」ことを目指さないこってす。つまり「時間のかかる列挙を完成プログラムに埋め込もうとしないこと」。それやっちゃうと、起動のたんびに猛烈列挙するハメになんぞ。

次。msc.log は、MSYS find が吐き出したものなので、「/c/Windows」のように MSYS 流儀のパスなのね。これは他のプログラムが困る。ので、これは手作業で(エディタで)置換しておく。

次。作った msc.log に基いて、mscファイルから興味のある情報だけ抜き出す加工。最初は sed でやってたし、ダルくなって python にしたけれど、真面目に XML 扱おうなんか 1ミリも考えない。こんな:

aaa.py
 1 # -*- coding: utf-8 -*-
 2 import os, re
 3 fnames = open("msc.log", "rb").read().strip().split("\n")
 4 d = {}
 5 for fn in fnames:
 6     try:
 7         cnt = open(fn, "rb").read().replace("\r\n", "")
 8         cnt = re.sub(" +", " ", cnt)
 9         cnt = re.search("<Strings>(.*)</Strings>", cnt).group(1)
10         cnt = re.sub("<String ", "<", cnt)
11         cnt = re.sub("</String>", ", ", cnt)
12         cnt = re.sub('<ID="([0-9]+)" Refs="([0-9]+)">', r"[\1-2]", cnt)
13         if cnt not in d:
14             d[cnt] = []
15         d[cnt].append(fn)
16     except IOError:
17         pass
18 
19 for cnt in d:
20     print("%s\t%s\t%s" % (os.path.basename(d[cnt][0]), d[cnt][0], cnt.decode("utf-8").encode("cp932")))

ほんとに aaa.py です。残すつもりがないものだし、見せる予定だってなかったしさ。あ、「IOError」ですが、これは謎。find で列挙できたもので開けないものがある。例の長過ぎるパス名、かも。完璧を目指す気は毛頭なかったので、黙って捨てました。

でこれを使って:

1 me@host: ~$ python aaa.py | sort > msc.log2

これによって、こんな msc.log2 になったとさ:

1 CIADV.MSC  c:/Windows/winsxs/amd64_microsoft-windows-i..-service-mmc-snapin_31bf3856ad364e35_6.1.7600.16385_none_76a3e7136851eccf/CIADV.MSC     [1-2]Console Root,  [2-2]Indexing Service on Local Machine,  [3-2]Indexing Service,  [4-2]Favorites,  
2 CIADV.MSC   c:/Windows/winsxs/amd64_microsoft-windows-i..mc-snapin.resources_31bf3856ad364e35_6.1.7600.16385_ja-jp_fa7f2f10862ebe4a/CIADV.MSC    [1-2]コンソール ルート,  [2-2]インデックス サービス - ローカル コンピューター,  [3-2]インデックス サービス,  [4-2]お気に入り,  
3 NAPCLCFG.MSC    c:/Windows/System32/NAPCLCFG.MSC     [1-2]Favorites,  [2-2]NAP Client Configuration(Local Computer),  [3-2]Console Root,  
4 ...(以下省略)...

で最後。「まとめあげ」部分:

bbb.py
 1 # -*- coding: utf-8 -*-
 2 import os, re, codecs, sys ; sys.stdout = codecs.getwriter('cp932')(sys.stdout)
 3 lines = open("msc.log2", "rb").read().strip().decode("cp932").split("\n")
 4 d = {}
 5 for line in lines:
 6     spl = line.strip().split("\t")
 7     if spl[0] not in d:
 8         d[spl[0]] = {"p": [], "d": []}
 9     d[spl[0]]["p"].append(spl[1])
10     d[spl[0]]["d"].append(re.sub(", *$", "", spl[2]))
11 
12 #print("#! /bin/sh")
13 for k in d:
14     if len(d[k]["p"]) == 2:
15         if "ja-" not in d[k]["p"][0]:
16             t = d[k]["p"][0]
17             d[k]["p"][0] = d[k]["p"][1]
18             d[k]["p"][1] = t
19             t = d[k]["d"][0]
20             d[k]["d"][0] = d[k]["d"][1]
21             d[k]["d"][1] = t
22     print("<h3>%s</h3>" % k)
23     print("<blockquote>")
24     for i in range(len(d[k]["p"])):
25         print(re.sub(r"\[([0-9])\-([0-9])\]", r"{ID=\1, Refs=\2}", u"%s" % "\n".join(d[k]["d"][i].split(", "))))
26         print("%s" % d[k]["p"][i])
27         #if i == 0:
28         #    print("cmd /c 'c:/Windows/System32/mmc %s'" % d[k]["p"][i])
29         #    print("sleep 5")
30         print("")
31     print("</blockquote>")
32     print("")

これも本当に bbb.py です。HTML 形式の出力にしてるのは WordPress にペタっと貼り付けたかったからね。「#! /bin/sh」とかがコメントアウトで混じってるのは、「全部一度は起動してみたい」をやってみた名残。

そうやって出来たのが「お前はどこのワカメじゃ(mscファイル)」でした。オシマイ。

さー、aaa.py、bbb.py、捨てよーっと。


そういえば、やってて「あら、Python で swap って、一撃で出来なかったかしら?」と頭をよぎったのだけれど、まぁいいや、と思って、手書き swap してます。なんかキレイなやり方ありそうな気がする。