基本JavaScript。時々Perl
- サクラエディタマクロ
textに書いた条件のGrep結果をひたすら追記する。
GrepにはWindowsのFinsStrコマンドを利用。
やりすぎ注意
MAX_LINE = 10;
CRLF = "\r\n";
switch(Editor.GetLineCode()) {
case 1: CRLF = "\n"; break;
case 2: CRLF = "\r"; break;
}
while(1) {
var path = [];
var mode = "";
var matcher = [];
var exp = [];
var case_flag = false;
var regexp_flag = false;
var result_row = 0;
var err_flag = false;
//**************************************************************************
// 編集中ファイルから検索条件パラメータを取得する
//**************************************************************************
for(var i = 1; i <= Editor.GetLineCount(0); i++) { // 行をループ
// 1行取得
var str = Editor.GetLineStr(i);
// 行頭と行末の余分なスペースをけずる
str = str.replace(/^\s*(.*?)\s*?$/, "$1");
// コメント(#)を削る
str = str.replace(/#.*$/, "");
if(str == null || str.length == 0) continue;
// []で囲まれた文字の取得
if(str.match(/^\[(\w+)\]$/)) {
// []の中身の文字を英小文字で前後のスペースを削って取得
mode = RegExp.$1.toLowerCase().replace(/^\s*(.*?)\s*?$/, "$1")
continue;
}
// []で囲まれていない場合
switch(mode) {
case "" : break; // まだ[]タグがないので放置して次へ
case "folder":
case "path" :
case "dir" : path.push(str); break; // パス指定取得
case "expand":
case "exp" : exp.push(str); break; // 拡張子取得
case "find" :
case "search":
case "match" : matcher.push(str); break; // 検索文字列取得
case "hilow" : case_flag = true; break; // 大文字小文字区別なし
case "regexp":
case "reg" : regexp_flag = true; break;
case "result": // 検索実施済み?
if(result_row == 0) result_row = i; // 場所を把握。
break;
default : err_flag = true; break; // それ以外はエラー
}
}
// 拡張子が指定されていないときのデフォルト
if(exp.length == 0) exp.push("*");
// ファイルの末尾に移動
Editor.GoFileEnd();
if(path.length == 0 || matcher.length == 0 || err_flag) {
// パラメータが足りない場合使い方を挿入してしまう。
Editor.InsText(CRLF);
Editor.InsText("[match]" + CRLF + CRLF);
Editor.InsText("# ここに検索文字を羅列する" + CRLF + CRLF);
Editor.InsText("[dir]" + CRLF + CRLF);
Editor.InsText("# ここに検索対象のパスを羅列する" + CRLF + CRLF);
Editor.InsText("[exp]" + CRLF + CRLF);
Editor.InsText("# ここに検索対象のファイルを羅列する" + exp + CRLF + CRLF);
Editor.InsText("#[hilow] # 大文字小文字を区別しない場合指定する" + CRLF);
break;
}
if(result_row > 1) {
var btn = Editor.YesNoBox("結果がすでに存在します。削除して上書きしますか?")
if(btn == null || btn == 0|| btn == 2 || btn == 3 || btn == 7) {
break;
}
Editor.Jump(result_row - 1);
Editor.GoLineTop(1);
Editor.BeginSelect();
Editor.GoFileEnd_Sel();
Editor.Delete();
}
// Resultタグ出力
Editor.InsText(CRLF + "[Result]" + CRLF);
// 検索開始時のファイル最終位置を保存する。
var result_row = Editor.GetLineCount(0);
//**************************************************************************
// 検索本体
//**************************************************************************
for(var j = 0; j < matcher.length; j++) { // 検索文字ループ
// 検索文字列出力
Editor.InsText("■■■■■■■■検索文字列:" + matcher[j] + "\t検索ファイルの拡張子:" + exp.join(","));
if(case_flag) Editor.InsText("\t大文字小文字を区別しない");
Editor.InsText(CRLF);
// 外部プログラム(windows標準コマンド利用)
var exec = "findstr /s /n /C:\"" + matcher[j] + "\"";
if(case_flag) exec += " /i" // 英大文字と英小文字を区別しない
if(regexp_flag) exec += " /r" // 正規表現
// %Aはのfor文の結果
exec += " /D:"+ path.join(";") + " " + exp.join(" ");
// ファイルの末尾に移動(コマンド実行中にカーソルが手で移動できてしまうので)
Editor.GoFileEnd();
// 今の最終ファイル位置を保存
var befor_editorline = Editor.GetLineCount(0);
Editor.ExecCommand(exec, 3); // 実行
// ファイルの末尾に移動(コマンド実行中にカーソルが手で移動できてしまうので)
Editor.GoFileEnd();
// 最終ファイル位置が変わらないときはキャンセル
if(befor_editorline == Editor.GetLineCount(0)) break;
}
break;
}
↑の結果をタグジャンプできるように変換するスクリプト
MAX_LINE = 10;
CRLF = "\r\n";
switch(Editor.GetLineCode()) {
case 1: CRLF = "\n"; break;
case 2: CRLF = "\r"; break;
}
while(1) {
// 今の位置取得
var result_row = Editor.ExpandParameter("$y");
//**************************************************************************
// FindStrの出力方式を普通のGrep方式(タグジャンプ対応)に変換します。
//**************************************************************************
// 検索完了後の最終ファイル位置を保存する。
var end_line = Editor.GetLineCount(0);
// 記録していた位置へカーソル移動
Editor.Jump(result_row);
// FindStrの検索したパス。
var path_str = "";
// FindStr実施行の正規表現
var reFindStr = new RegExp("^.+?findstr +?/s +?/n +?/C:.+? +?/D.+? .+$");
// FindStrが出力する検索結果行
var reResult = new RegExp(":(\\d+):\\s*");
while(1) {
// 今の最終ファイル位置を保存
var befor_editorline = Editor.GetLineCount(0);
// 1行取得
var str = Editor.GetLineStr(0);
// 末尾の改行記号を削除
str = str.replace(/[\r\n]+$/, "");
var del_flag = false;
// 先頭にスペース2文字があるかつ、末尾が:の行がFindStrのパス出力。
if(str.match(/^ (.*?):$/)) {
path_str = RegExp.$1; // パス取得
del_flag = true;
}
// 改行のみの行か、FindStr実施行ならいらない行
if(del_flag || str == null || str.length == 0 || reFindStr.exec(str) != null) {
Editor.DeleteLine(); // この行はいらないので消す
// 行削除済みなのでrowはカウントしたくないのでそのまま繰り返し
} else {
// 検索文字列行かを判別
if(str.match(/^■■■■■■■■検索文字列:/)) {
Editor.Down(); // 検索文字列行は残す
} else {
// それ以外は検索結果。
Editor.DeleteLine(); // 一旦消す。
// ファイル位置との区切り記号をタブ区切に(エクセル貼り付け用)
str = str.replace(reResult, "\t$1\t");
// FindStrのパスを付加
if(path_str != null && path_str.length > 0) Editor.InsText(path_str + "\\");
Editor.InsText(str + CRLF); // 貼り付け治す
}
result_row++; // 次の行へ
}
if(befor_editorline < Editor.GetLineCount(0)) break; // 暴走防止用
if(Editor.GetLineCount(0) <= result_row) break; // 最終行なら終了
}
break;
}
目的不明・・・private methodを消すとかに使ったのか?
var start_line = 1;
var end_line = Editor.GetLineCount(0); //論理行数を取得
CRLF = "\r\n";
switch(Editor.GetLineCode()) {
case 1: CRLF = "\n"; break;
case 2: CRLF = "\r"; break;
}
if(Editor.IsTextSelected != 0) {
// 選択状態なら先頭行と末尾行を取得
start_line = Editor.GetSelectLineFrom();
end_line = Editor.GetSelectLineTo();
// レイアウト行から論理行へ変換
start_line = Editor.LayoutToLogicLineNum(start_line)
end_line = Editor.LayoutToLogicLineNum(end_line)
}
while(1) {
var mth = Editor.InputBox("検索結果のある行を削除します。検索文字を指定してください", "", 64);
if(mth == null || mth == "") break;
var m = new RegExp(mth, 'i');
Editor.Jump(start_line);
for(var i = start_line; i <= end_line; ) { // 行をループ
var str = Editor.GetLineStr(0); // 1行取得
str = str.replace(/[\r\n]+$/, "");
if(str.match(m)) { Editor.DeleteLine(); end_line--; }
else { Editor. Down(); i++; }
}
break;
}
- WSH(EXCELやCSVをADOで操作)
JOINができないのが痛い。。。
- C#のソースからnamespace/class/methodの一覧を作成(csv)する。
関数が現れた場所と、コメントのようなものも表になる。
エクセルにソース一覧を作っとかないとダメだし、SJIS以外はダメだが。
var path = "C:\\Users\\takahara.kosuke\\Documents";
var file = "PS全検索結果.xlsx";
var outfile_name = "関数一覧.csv";
var regComment = /\/\*.*\*\//g;
var regMethod = /(([A-Za-z][0-9A-Za-z:\.\[\]]*\s+)+[A-Za-z][0-9A-Za-z:\[\]]*\s*)\(/;
comment = "";
line_buf = 0;
String.prototype.dqe = function() {
var ret = '"';
for(var i = 0; i < this.length; i++) {
var c = this.charAt(i);
ret += c;
if(c == '"') ret += c;
}
return ret + '"';
};
String.prototype.trim = function() {
return this.replace(/^\s*(.*?)\s*$/g, "$1");
};
String.prototype.lineCommentDelete = function() {
var ret = this.replace(/#.*$/, "").replace(/\/\/(.*)$/, "");
comment += RegExp.$1;
// 予約語で始まるものは消す
return ret.trim().replace(/^(this\.|(new|using|else|return|for|switch|while|if|do)\s).*$/g, "");
};
String.prototype.tipMatch = function(reg) {
var ret = {result: false, string : "", note : ""};
// コメントの中身を退避
var arr = this.match(regComment);
if(arr) {
for(var i in arr) {
comment += ("" + arr[i]).substr(2, arr[i].length - 4).trim();
}
}
var str = this.replace(regComment, "").trim();
if(str.match(/^\/\*/)) { // 間違ってコメントの中で止まってる。
comment += RegExp.rightContext.trim();
return ret;
}
str = str.replace(/^.*\}/g, "").replace(/\{.*$/, "").trim().replace(/^\[.*\]/, "").trim();
if(str.length < 2) return ret;
var flag = str.match(reg);
if(!flag) return ret;
var str = RegExp.lastMatch + RegExp.rightContext;
ret = {result: true, string: str.trim(), note: comment.replace(/^.*\}/g, "").replace(/\{.*$/, "").replace(/[=\/\*\-#]+/g, "").trim()};
comment = "";
return ret;
};
var driver = "Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)"
var readonry = true;
var fso = new ActiveXObject("Scripting.FileSystemObject")
var log = fso.CreateTextFile(path +"\\"+outfile_name+".log", true);
var xls = new ActiveXObject("ADODB.Connection");
xls.Open("Driver={" + driver + "}; DBQ=" + path +"\\" + file + ";ReadOnly=" + (readonry ? 1: 0));
var outfile = fso.CreateTextFile(path +"\\" + outfile_name, true);
outfile.WriteLine("No,ソース,資源,資源タイプ,場所,コメント");
var count = 0;
var sql = "SELECT [ソース] AS Src FROM [ソース一覧$]";
var rs = xls.Execute(sql);
for(; !rs.Eof; rs.MoveNext()) {
var src = new String(rs("Src"));
if(src == null || src.length == 0) continue;
// ソースを開く
var frs = fso.OpenTextFile(src, 1);
comment = "";
line_buf = 0;
var line = 0;
var buf = "";
// ソースの最後までループ
while(!frs.AtEndOfStream) {
line++; // ソース内の行数
// ソールから1行読みコメントっぽいところを削ってバッファに足す
buf += frs.ReadLine().lineCommentDelete();
if(buf.length > 0 && line_buf == 0) line_buf = line;
// 末端記号(;)があるところは要らない
if(buf.indexOf(";") >= 0) {
buf ="";
line_buf = 0;
continue;
}
// ブロックの開始以外はバッファに足すだけ
if(buf.indexOf("{") < 0) continue;
// メソッドっぽい
var e = buf.tipMatch(regMethod);
if(e.result) e.type = "function";
else {
// クラスっぽい
e = buf.tipMatch(/\s*class\s+\w+/);
if(e.result) {
e.string = e.string.replace(/\s*:.*$/, "");
e.type = "class";
} else {
// ネームスペースっぽい
e = buf.tipMatch(/\s*namespace\s+\w+/);
if(e.result) e.type = "namespace";
}
}
if(e.result) {
count++;
outfile.WriteLine(
[count, src.dqe(), e.string.dqe(), e.type, line_buf, e.note.dqe()].join(","));
}
buf = ""
comment ="";
line_buf = 0;
}
// ソースを閉じる
frs.Close();
frs = null;
}
rs.Close();
rs = null;
xls.Close();
xls = null;
outfile.Close();
outfile = null;
fso = null;
var wsh = WScript.CreateObject("WScript.Shell")
wsh.Popup("完了しました", 5, outfile_name, 0 + 64)
wsh = null;
縦にGrep結果、横にパターン1・2・・・・みたいな表を作ってしまったのでこれをまとめるためのもの。
まあUNIONで集計してるだけだが。
String.prototype.dqe = function() {
var ret = '"';
for(var i = 0; i < this.length; i++) {
var c = this.charAt(i);
ret += c;
if(c == '"') ret += c;
}
return ret + '"';
}
var output = "GROUP.csv";
var excel_driver = "Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)"
var path = "C:\\Users\\takahara.kosuke\\Documents";
var file = "PS全検索結果.xlsx";
var csv_driver = "Microsoft Text Driver (*.txt; *.csv)"
var xls_readonry = true;
var csv_readonry = false;
var sql;
var line;
var str;
var func = [];
var fso = new ActiveXObject("Scripting.FileSystemObject")
var log = fso.CreateTextFile(path +"\\wsh.log", true);
var xls = new ActiveXObject("ADODB.Connection");
var csv = new ActiveXObject("ADODB.Connection");
xls.Open("Driver={" + excel_driver + "}; DBQ=" + path +"\\" + file + ";ReadOnly=" + (xls_readonry ? 1: 0));
csv.Open("Driver={" + csv_driver + "}; DBQ=" + path + ";ReadOnly=" + (csv_readonry ? 0: 1));
sql = "SELECT Top 1 * FROM [計画修正のみ$]"
var rs = xls.Execute(sql);
var max = 0;
var ar = [];
for(var i = 0; i < rs.Fields.Count; i++) {
var name = new String(rs.Fields(i).Name);
if(name.match(/^パターン(\d+)$/)) {
var m = parseInt(RegExp.$1);
if(max < m) max = m;
}
}
rs.Close();
var ws = fso.CreateTextFile(path +"\\" + output, true);
sql = "";
for(var i = 0; i < max; i++) {
var type = "分類" + (i+1);
var pattern = "パターン" + (i+1);
if(i>0) sql += " UNION ";
sql += "SELECT [" + type + "] AS T, [" + pattern + "] AS P FROM [計画修正のみ$]";
}
sql += " ORDER BY T ASC, P ASC";
WScript.Echo(sql);
rs = xls.Execute(sql);
for(; !rs.Eof; rs.MoveNext()) {
ws.WriteLine('"'+rs("T")+'","'+rs("P")+'"');
}
rs.Close();
rs = null;
ws.Close();
ws = null;
xls.Close();
xls = null;
csv.Close();
csv = null;
log.Close();
log = null;
fso = null;
もうなんだ、一斉Grepに戻ってないか?
var output = "サマリ.csv";
var path = "C:\\Users\\takahara.kosuke\\Documents";
var file = "PS全検索結果.xlsx";
var wsh = WScript.CreateObject("WScript.Shell")
String.prototype.dqe = function() {
var ret = '"';
for(var i = 0; i < this.length; i++) {
var c = this.charAt(i);
ret += c;
if(c == '"') ret += c;
}
return ret + '"';
}
var excel_driver = "Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)"
var csv_driver = "Microsoft Text Driver (*.txt; *.csv)"
var readonry = true;
var sql;
var l;
var func = [];
var fso = new ActiveXObject("Scripting.FileSystemObject")
var log = fso.CreateTextFile(path +"\\wsh.log", true);
var xls = new ActiveXObject("ADODB.Connection");
var rs;
xls.Open("Driver={" + excel_driver + "}; DBQ=" + path +"\\" + file + ";ReadOnly=" + (readonry ? 1: 0));
sql = "SELECT [ソース], [資源], [資源タイプ], [場所] FROM [資源一覧$]";
for(rs = xls.Execute(sql); !rs.Eof; rs.MoveNext()) {
var src = rs("ソース");
if(!(src in func)) func[src] = [];
func[src].push({object: new String(rs("資源")), type: new String(rs("資源タイプ")), line: new String(rs("場所"))});
}
rs.Close();
rs = null;
var pattern = [];
sql = "SELECT [#] AS N, [分類] AS T, [パターン] AS P FROM [使用パターン一覧$]";
for(rs = xls.Execute(sql); !rs.Eof; rs.MoveNext()) {
pattern[rs("P")] = {
'No': parseInt(rs("N")),
'Type' : new String(rs("T"))
}
}
sql = "SELECT Top 1 * FROM [計画修正のみ$]"
rs = xls.Execute(sql);
var max = 0;
var ar = [];
for(var i = 0; i < rs.Fields.Count; i++) {
var name = new String(rs.Fields(i).Name);
if(name.match(/^パターン(\d+)$/)) {
var m = parseInt(RegExp.$1);
if(max < m) max = m;
}
}
rs.Close();
rs = null;
sql = ""
for(var i = 0; i < max; i++) {
if(i > 0) sql += " UNION ALL ";
sql += "SELECT [No], [フォルダ], [ソース], [行], [列], [コード],[パターン" + (i+1) + "] AS P";
sql += " FROM [計画修正のみ$]"
}
var btn = wsh.Popup(sql, 10, "実行します", 1 + 64)
if(btn == 1) {
var ws = fso.CreateTextFile(path +"\\" + output, true);
ws.WriteLine("No,ソース,行,列,コード,分類No,分類,パターン,クラス,クラス行,関数,関数行");
for(rs = xls.Execute(sql); !rs.Eof; rs.MoveNext()) {
var ptn = new String(rs("P"));
if(!ptn) continue;
if(ptn.length < 2) continue;
l = parseInt(rs("行"));
var src = new String(rs("ソース"));
var code = new String(rs("コード"));
var src_file = "z:\\" + rs("フォルダ") + "\\" + rs("ソース");
var parm = {
no: 0,
type: "-",
function_t: {line: 0, str: ""},
class_t: {line: 0, str: ""}
};
if(ptn in pattern) {
parm.no = pattern[ptn].No;
parm.type = pattern[ptn].Type;
}
if(!parm.no) continue;
for(var j in func[src_file]) {
if(func[src_file][j].line > l) break;
if(func[src_file][j].type == "function") {
parm.function_t.str = func[src_file][j].object;
parm.function_t.line = func[src_file][j].line;
} else
if(func[src_file][j].type == "class") {
parm.class_t.str = func[src_file][j].object;
parm.class_t.line = func[src_file][j].line;
}
}
ws.WriteLine([
rs("No"), src.dqe(), l, rs("列"), code.dqe(),
parm.no, parm.type.dqe(), ptn.dqe(),
parm.class_t.str.dqe(), parm.class_t.line,
parm.function_t.str.dqe(), parm.function_t.line
].join(','));
}
rs.Close();
rs = null;
ws.Close();
ws = null;
wsh.Popup("完了しました", 10, output, 0 + 64)
wsh = null;
}
xls.Close();
xls = null;
log.Close();
log = null;
fso = null;
あほすぎるが・・・
var path = "C:\\Users\\takahara.kosuke\\Documents";
var file = "PS全検索結果.xlsx";
var outfile_name = "クラス一覧.csv";
comment = "";
line_buf = 0;
String.prototype.dqe = function() {
var ret = '"';
for(var i = 0; i < this.length; i++) {
var c = this.charAt(i);
ret += c;
if(c == '"') ret += c;
}
return ret + '"';
};
String.prototype.trim = function() {
return this.replace(/^\s*(.*?)\s*$/g, "$1");
};
var driver = "Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)"
var readonry = true;
var fso = new ActiveXObject("Scripting.FileSystemObject")
var log = fso.CreateTextFile(path +"\\"+outfile_name+".log", true);
var xls = new ActiveXObject("ADODB.Connection");
xls.Open("Driver={" + driver + "}; DBQ=" + path +"\\" + file + ";ReadOnly=" + (readonry ? 1: 0));
var outfile = fso.CreateTextFile(path +"\\" + outfile_name, true);
outfile.WriteLine("No,ソース,行,クラス,コメント");
var count = 0;
var sql = "SELECT [No],[クラス] FROM [クラス一覧$]";
var rs;
for(rs = xls.Execute(sql); !rs.Eof; rs.MoveNext()) {
var sql = "SELECT [ソース], [場所], [コメント] FROM [資源一覧$]"
+ " WHERE [資源タイプ] = 'class' AND [資源] = '" + rs("クラス") + "'";
var rss;
for(rss = xls.Execute(sql); !rss.Eof; rss.MoveNext()) {
outfile.WriteLine(
[rs("No"), String(rss("ソース")).dqe(), String(rs("クラス")).dqe(), rss("場所"), String(rss("コメント")).dqe()].join(","));
}
rss.Close();
rss = null;
}
rs.Close();
rs = null;
xls.Close();
xls = null;
outfile.Close();
outfile = null;
fso = null;
var wsh = WScript.CreateObject("WScript.Shell")
wsh.Popup("完了しました", 5, outfile_name, 0 + 64)
wsh = null;
最終更新:2013年04月03日 17:03