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ミリも考えない。こんな:
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 ...(以下省略)...
で最後。「まとめあげ」部分:
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 してます。なんかキレイなやり方ありそうな気がする。