Macro/投稿/133

http://sakura.qp.land.to/?Macro%2F%C5%EA%B9%C6%2F133


Top > Macro > 投稿 > 133

Grep結果から複数のファイルをまとめて置換処理

  • ページ: Macro/投稿
  • 作者: すい?
  • カテゴリー: ppa
  • 投稿日: 2003-02-01 (土) 20:52:58

メッセージ

fileGREPREP.PPA
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
// Grep結果から複数のファイルに対して置換処理をまとめておこなう。
 
// TAB=4
// 実行には PPA.DLL が必須です。PPA.DLL を入手して sakura.exe と同じフォルダに入れておいてください。
// マクロファイルの拡張子は .PPA でなくてはなりません。
 
// 複数ファイルに対して一気に [全て置換] を実行します。
// Grep結果形式のテキストから、「各種の検索条件」と「処理対象のファイル名リスト」を取得し、
// それら処理対象のファイルに対して「全て置換」を実行していくマクロです。
// 
// ★ 基本的な使用手順
// 1.Grep をおこなう。    ※ 結果出力形式は「ノーマル」を選択しておいてください。
// 2.Grep 結果の先頭行(1行目)に「置換後の文字列」を書き込んでおく。
// 3.このマクロを実行する。
// 
// 例えば
// 「フォルダ C:\Hoge\ 以下にある複数のファイル *.pl ,*.cgi の中の
//  文字列 perl を jperl に置換したい。」
// なら、
// 1.Grep で
//   検索条件:perl
//   ファイル:*.pl *.cgi
//   フォルダ:C:\Hoge
//   他、サブフォルダ、英大小文字の区別、正規表現、なども指示して Grepを実行する。
// 
// 2.Grep が完了したら、Grep結果表示ウィンドウの先頭行に「jperl」と入力する。
//   1|jperl	← ここに記述する
//   2|□検索条件  "perl"
//   3|検索対象   *.pl *.cgi
// 
// 3.このマクロを実行する。
// 
// すると、簡単な置換処理内容の確認ダイアログが出ます。
// 処理内容は
//  「 Grep で見つけたファイル群に対して、Grepの検索条件文字列を指定の置換後文字列に、
//   Grep時の条件(英大小区別する?正規表現使う?など)で、一気に「すべて置換」処理する。」
// という物になります。
// 確認ダイアログに対して [はい] と答えると、その置換処理が複数ファイル群に対して一気に実行されます。
// 
// 先に Grep結果と同じ形式のテキストファイルを作っておいて、サクラエディタで開いておいてから
// このマクロを実行したりしても構いません。
// 
// ※ マクロ内の変数 affF の値により、ファイル毎に「置換処理の実行をする/しない」の
//   確認ダイアログを<出す/出さない>の指定が可能です。
// 
// ※ 「このマクロを実行開始するエディタウィンドウ」以外のサクラエディタのウィンドウを
//   全て閉じておいてから実行してください。
 
var
	tp:Integer;		// 整数数値変数 tp を用意 - 作業用
	str:String;		// 文字列変数 str を用意 - 作業用
	this:String;	// 文字列変数 this を用意 - マクロを実行開始したファイル名を記憶しておく
	aft:String;		// 文字列変数 aft を用意 - 置換後の文字列
	bef:String;		// 文字列変数 bef を用意 - 置換前の文字列
	CRLF:String;	// 文字列変数 CRLF を用意 - 改行文字列を入れて使いまわす
	sp,mess,cond:String;	// 文字列変数 mess を用意 - ダイアログメッセージを格納するため
	word,ignr,re,messNF,Aclose,Loop,Clip,Fsel:Integer;	// 整数数値変数を用意 - Grep の条件の値を入れておく
	option:Integer;	// 整数数値変数 option を用意 - Grep の条件指定
	files,LastF:String;	// 文字列変数を用意 - 処理対象ファイルのリスト、及びリスト作成に使用する作業用変数
	affF:Integer;	// 確認するかどうか。
begin	// {
	// ************************************************** //
	//                        設定                        //
	// ************************************************** //
	affF := 1;		// ファイル毎に「このファイルに対して置換処理を実行するかどうか」
					// を確認するかどうか。( 0:確認しない / 1:確認する )
 
	// ************************************************** //
	//                  ここより処理開始                  //
	// ************************************************** //
	// ↓CRLF に改行文字を格納しておく。
	CRLF := '
';
	// ↓S_ReplaceAll / S_SearchNext のオプション値(定数)
	word   := $01;	// bit0:単語単位で探す
	ignr   := $02;	// bit1:英大文字と小文字を区別する
	re     := $04;	// bit2:正規表現
 
	messNF := $08;	// bit3:見つからないときにメッセージを表示
	Aclose := $10;	// bit4:置換(検索)ダイアログを自動的に閉じる
	Loop   := $20;	// bit5:先頭(末尾)から再検索する
	Clip   := $40;	// bit6:クリップボードから貼り付ける
	Fsel   := $80;	// bit7:0=ファイル全体 / 1=選択範囲
 
	option := Aclose;	// 「置換ダイアログを自動的に閉じる」ON
 
	// ************************************************** //
	//                   置換条件を取得                   //
	// ************************************************** //
	// 置換後文字列(先頭行の内容)を取得する
	S_GoFileTop(0);					// ファイルの先頭に移動
	S_Down_Sel(0);					// (選択)カーソル下移動
	aft := S_GetSelectedString(0);	// 選択部分の文字列を取得
	S_CancelMode(0);				// 各種モードの取り消し - 文字列選択を解除
 
	if ( aft = '' )	then	// 置換後文字列が空文字列だった
	begin	// {
		// *** 確認ダイアログを出す *** //
		mess := '';
		mess := mess + '置換後の文字列が空です。よろしいですか?' +CRLF;
		mess := mess + '( [はい] と答えると、「検索対象文字列を削除する処理」という事になります。)' +CRLF;
		mess := mess + '' +CRLF;
		mess := mess + '※ 置換後の文字列を、Grep結果の先頭行(1行目)に記述してから実行してください。' +CRLF;
		if( MessageBox(mess,'確認です。',$123) <> 6 )	then	Exit;	// [はい] 以外ならマクロ終了
	end;	// }
 
	// 検索文字列、検索時の条件(英大小区別?正規表現?etc...)を取得する。
	bef := '';		// 検索文字列 - 空にしておく
	for	tp := 0	to 20 do	// 本当は無限ループで良いハズだが、「Grep結果」以外のファイルから このマクロが
							// 実行された場合の対策として念のため回数(調査する行数)制限しておいた。
	begin	// {
 
		// カーソル行を str へ取得し、次の行へ移動しておく
		S_Down_Sel(0);							// (選択)カーソル下移動
		str := Trim(S_GetSelectedString(0));	// 選択文字列を前後の空白文字の類を削除して str に格納
		S_CancelMode(0);						// 各種モードの取り消し - 文字列選択を解除
 
		if ( str = '' )	then	break;		// 行が空行だった = Grep条件部の終わり位置 → ループ脱出
 
		if( Copy(str,1,10) = '□検索条件' )	then	// 検索文字列が記述されている行である。
			begin	// {
				str := Trim(Delete(str,1,10));
				bef := Copy( str , 2 , Length(str)-2 );
			end 	// }
		else if( str = '(単語単位で探す)'           )	then	option := option or word	// 単語単位 on
		else if( str = '(正規表現)'                 )	then	option := option or re		// 正規表現 on
		else if( str = '(英大文字小文字を区別する)' )	then	option := option or ignr	// 大小区別 on
		;
	end;	// }
 
	if ( bef = '' )	then	// 検索文字列が見つからなかった場合 - エラー終了
		begin	// {
			S_MoveHistPrev(0);	// 移動履歴: 前へ - S_GoFileTop
			mess := '';
			mess := mess + '開かれているファイルが Grep結果ではないようです。' +CRLF;
			mess := mess + '本マクロは Grep結果から実行してください。' +CRLF;
			MessageBox(mess,'エラー終了',0);
			Exit;
		end 	// }
	;
 
	// ************************************************** //
	//        処理対象のファイル名リストを取得する        //
	// ************************************************** //
	// ファイルリスト部 以外を削除しておく
 
	// 検索条件欄を削除する。
	S_GoFileTop_Sel(0);	// (選択)ファイルの先頭に移動
	S_Delete(0);	// 削除
 
	// 検索結果欄から先頭のファイル名部分のみを残して後ろを削除する。
//	S_ReplaceAll('^(..[^:]*)\([0-9]*,?[0-9]*\):.*','$1',re);
	S_ReplaceAll( '^(..[^:]*)\([0-9]*,?[0-9]*\)( *\[(SJIS|JIS|EUC|Unicode|UniBE|UTF-[78])\])?:.*' , '$1' , re + ignr );
 
	// 検索結果ファイル末尾の「?? 個が検索されました。」を削除
	S_GoFileEnd(0);	// ファイルの最後に移動
	S_Up(0);		// カーソル上移動
	S_CutLine(0);	// 行切り取り(折り返し単位)
 
	// 重複するファイル名を削除 - するための準備として、念のために名前順に並べておく
	S_SelectAll(0);	// すべて選択
	S_SortAsc(0);	// 選択行の昇順ソート
//	S_Merge(0);		// 選択行のマージ - ダイアログが出るため、処理が一時中断するので使うのをやめた。
 
	S_CancelMode(0);		// 各種モードの取り消し - 文字列選択を解除
	S_SearchClearMark(0);	// 検索マークの切替え
 
	// (重複する物を省きながら)ファイル名を files に格納していく
	LastF := '';		// 最後に取得したファイル名を格納しておく変数
	files := '';		// ファイルのリストを格納していく変数
	S_GoFileTop(0);		// ファイルの先頭に移動
 
	S_Down_Sel(0);							// (選択)カーソル下移動
	str := Trim(S_GetSelectedString(0));	// 選択文字列を前後の空白文字の類を削除して str に格納
	S_CancelMode(0);						// 各種モードの取り消し - 文字列選択を解除
 
	if ( str = '' )	then	// 空行だったら
		begin	// {
			S_Down_Sel(0);							// (選択)カーソル下移動
			str := Trim(S_GetSelectedString(0));	// 選択文字列を前後の空白文字の類を削除して str に格納
			S_CancelMode(0);						// 各種モードの取り消し - 文字列選択を解除
		end 	// }
	;
 
	repeat	// ファイル名を取得していくループ
	// {
		if ( str <> LastF )	then	files := files + str + CRLF	;
		LastF := str;
 
		// 次の行の内容を取得する
		S_Down_Sel(0);							// (選択)カーソル下移動
		str := Trim(S_GetSelectedString(0));	// 選択文字列を前後の空白文字の類を削除して str に格納
		S_CancelMode(0);						// 各種モードの取り消し - 文字列選択を解除
	// }
	until( str = '' );		// 取得した文字列が空文字列ならばループを抜ける
 
	// ↑取得完了。↓以下、後始末。(Grep結果をこのマクロ実行前の状態に戻し、カーソル位置も元に戻す。)
	S_Undo(0);		// 元に戻す - S_SortAsc
	S_Undo(0);		// 元に戻す - S_CutLine
	S_Undo(0);		// 元に戻す - S_ReplaceAll
	S_Undo(0);		// 元に戻す - S_Delete
	S_MoveHistPrev(0);	// 移動履歴: 前へ - S_GoFileTop
	S_MoveHistPrev(0);	// 移動履歴: 前へ - S_SelectAll
	S_MoveHistPrev(0);	// 移動履歴: 前へ - S_GoFileEnd
	S_MoveHistPrev(0);	// 移動履歴: 前へ - S_ReplaceAll
	S_MoveHistPrev(0);	// 移動履歴: 前へ - S_GoFileTop_Sel
	S_MoveHistPrev(0);	// 移動履歴: 前へ - S_GoFileTop
	S_CurLineCenter(0);	// カーソル行をウィンドウ中央へ
 
	if ( files = '' )	then	// 処理対象ファイルが見つからなかった場合 - エラー終了
		begin	// {
			mess := '';
			mess := mess + '処理対象のファイルが見つかりませんでした。' +CRLF;
			MessageBox(mess,'エラー終了',0);
			Exit;
		end 	// }
	;
 
	// ************************************************** //
	//        実行開始の確認ダイアログを作成する。        //
	// ************************************************** //
	cond := '';		// 置換処理内容を記述したメッセージ文
	mess := '';		// cond の内容以外のメッセージ文
 
	// 文字列長合計を 60 にするためのスペース文字列 sp を生成
	sp   := '';	if Length(bef) < 60	then	for	tp:=1	to	60 - Length(bef)	do	sp := sp + ' ';
	cond := cond + '置換前:[' + bef + sp + '] ' + IntToStr(Length(bef)) + ' バイト' +CRLF;
 
	// 文字列長合計を 60 にするためのスペース文字列 sp を生成
	sp   := '';	if Length(aft) < 60	then	for	tp:=1	to	60 - Length(aft)	do	sp := sp + ' ';
	cond := cond + '置換後:[' + aft + sp + '] ' + IntToStr(Length(aft)) + ' バイト' +CRLF;
 
									cond := cond + '    		on/off' +CRLF;
	if ( option and word )	then	cond := cond + '単語単位で探す	■ □' + CRLF
	else							cond := cond + '単語単位で探す	□ ■' + CRLF	;
	if ( option and re   )	then	cond := cond + '正規表現		■ □' + CRLF
	else							cond := cond + '正規表現		□ ■' + CRLF	;
	if ( option and ignr )	then	cond := cond + '英大小を区別する	■ □' + CRLF
	else							cond := cond + '英大小を区別する	□ ■' + CRLF	;
 
	mess := mess + '' +CRLF;
	mess := mess + '[処理対象ファイル]' +CRLF;
	mess := mess + files +CRLF;
	mess := mess + '※ このウィンドウ以外のサクラエディタのウィンドウは全て閉じておいてください。' +CRLF;
 
	if( affF = 0)	then	// ファイル毎に置換処理の確認をしない場合
		begin	// {
			mess := mess + '' +CRLF;
			mess := mess + '※ [はい] で処理を開始すると、以降、確認画面は出ず、一気に置換処理されます。' +CRLF;
			mess := mess + '  中断もできません。' +CRLF;
		end 	// }
	;
 
	this := S_GetFilename( );
	if ( this = '' )	then	// ファイル名が無い場合 - Grep 結果から直接(Grep結果をファイルに保存せずに)実行している
		begin	// {
			mess := mess + '' +CRLF;
			mess := mess + '※ 実行するとGrep検索結果が消滅します。今の Grep検索結果が必要な場合は、' +CRLF;
			mess := mess + '  先に、ファイルとして「名前を付けて保存」してから実行してください。' +CRLF;
		end 	// }
	;
	mess := mess + '' +CRLF;
	mess := mess + '実行してもよろしいですか?' +CRLF;
	if ( MessageBox( cond + mess,'ファイル全体に対して、以下の条件で [すべて置換] を実行します',$123) <> 6 )	then	Exit;	// [はい] 以外ならマクロ終了
 
	// ************************************************** //
	//                  ここより置換実行                  //
	// ************************************************** //
	while ( True )	do	// 無限ループ
	begin	// {
		if ( files = '' )	then	Break;	// 残りの処理対象ファイルが無くなったらループ脱出
 
		// 処理対象ファイルリスト files から1ファイル名ずつ str に取り出す。
		// files からは取り出したファイル名を削除していく。
		tp := Pos(CRLF,files);	// ファイル名のセパレータ CRLF(改行)の場所を探す。
		if( tp <> 0 )	then	// CRLF があった。
			begin	// {
				str   := Copy  ( files , 1 , tp-1              );	// CRLF の前までの文字列を str に格納する。
				files := Delete( files , 1 , tp-1+Length(CRLF) );	// CRLF の後ろの文字列を files に格納する。
			end 	// }
		else	// CRLF が無かった → 残りの文字列は最後のファイル名そのものである
			begin	// {
				str   := files;	// 最後のファイル名そのものを str に格納する。
				files := '';	// 「残りのファイル」は“無し”の状態にする。
			end 	// }
		;
 
		if( str <> '' )	then	// 処理対象のファイル名が取得できていたら
			begin	// {
				// *** 置換処理メイン *** //
				S_FileClose();			// 閉じて(無題)
				S_FileOpen( str );		// 開く - 処理対象のファイルを開く
 
				if( affF <> 0 )	then	// ファイル毎に置換処理の確認をする場合
					begin	// {
						// ↓開いたファイル中の置換対象文字をマーク表示させて目立たせるための処理
						S_SearchNext( bef , option );	// 次を検索
						S_CancelMode(0);	// 各種モードの取り消し
 
						mess := '';			// 確認ダイアログのメッセージを作成する。
						mess := mess + '処理対象ファイル' +CRLF;
						mess := mess + '→ ' + str +CRLF;
						mess := mess + '' +CRLF;
						mess := mess + 'このファイルに対して置換処理(一気に全て置換)を実行しますか?';
						if( MessageBox( cond + CRLF + mess , str , $123 ) <> 6 )	then	Continue;	// [はい] 以外なら次のループ(次のファイル)へ
					end 	// }
				;
 
				S_ReplaceAll(bef,aft,option);	// 全て置換
				S_FileSave();					// 上書き保存
			end 	// }
		;
	end;	// }
	S_FileClose();	// 閉じて(無題)
 
	// this は、このマクロを起動した時、開いていたファイル名
	if ( this <> '' )	then	S_FileOpen(this);	// 元のファイルを開く
 
	MessageBox('全ファイルに対して置換処理を完了しました','置換終了',0);
 
	// this は、このマクロを起動した時、開いていたファイル名 = 空 ならば Grep結果から(ファイルに保存せずに)直接実行していた。
	if ( this = '' )	then	S_WinClose();	// ウィンドウを閉じる
 
end;	// }
 
//	2003/01/28 23時版
//		・初版
//	
//	2003/01/29
//		・Grep結果以外のファイルから起動した場合に無限ループに陥ってしまうことに対する対策が
//		 全く動作していなかった。
//		 while ループで tp を使ってループ回数制限しているつもりが tp の値を ++ するのを忘れ
//		 ていた超ポカミス。間違えようがないよう、回数指定ループ for に変えてしまった。
//		・他、注釈等の見直し。
//	2003/02/01 20時版
//		・文字コードセットを「自動選択」で Grep した時の Grep結果に対応していなかったのを修正。
 

aftに改行文字も取り込んでしまうため、修正。
     : S_Left_Sel(0);				// 追加
92 : aft := S_GetSelectedString(0);	// 選択部分の文字列を取得
     : S_Right_Sel(0);				// 追加
-- [[iwa]] &new{2009-08-01 (土) 18:28:23};

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

添付ファイル: fileGREPREP.PPA 1205件 [詳細]

リロード   新規 編集 凍結 差分 添付 複製 名前変更   ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2009-08-01 (土) 18:34:05 (5344d)