C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[11]: フォルダ内のテキストファイルの文字列を変換する方法2


(過去ログ 11 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■2690 / inTopicNo.1)  フォルダ内のテキストファイルの文字列を変換する方法2
  
□投稿者/ ろん (7回)-(2007/04/13(Fri) 13:57:01)

分類:[VB6 以前] 

皆様こんにちは。
タイトルの通り、フォルダ内のテキストファイルの文字列を変換する方法について
ご質問させていただきます。
ファイルを検索するところまでは、出来たのですが
文字列を検索して、置き換えるところがうまくいきません。
最後にモジュールを貼らせて頂きますので、識者の皆様どうかご教授ください。

【やりたいこと】
1.特定のフォルダ内及びサブフォルダ内の特定拡張子のファイルを全て検索する。
2.該当のファイル内にある特定の文字列を別の文字列に置き換える。

【備考】
該当ファイルは、テキストで編集できる1レコード80バイトの
固定長ファイルと考えます。

【モジュール】

Public Const Old_Word1 = "SERVER="
Public Const New_Word1 = "CONNECTION="
Public Const Out_Dir = "C:\apps\"
Option Compare Text
                
Type Record
   Len_Data As String * 80
End Type
'
'
'
Sub Main()
    Dim Out_SubDir As String
    Dim WK_Msg As String
    Dim FSO As Object, Fol As Object, MyFol As Object
    Dim MyFile As Object

    ChDir Out_Dir
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set Fol = FSO.GetFolder(Out_Dir)
    For Each MyFol In Fol.SubFolders
        Out_SubDir = Out_Dir & MyFol.Name

        For Each MyFile In MyFol.Files
→ここから
            If MyFile.Name Like "*.ACX" Then
                out_file = Out_SubDir & "\" & MyFile.Name
                Dim MyRecord As Record, RecordNumber
                Open out_file For Random As #2 Len = Len(MyRecord)
                For RecordNumber = 1 To 999
                    Get #2, RecordNumber, MyRecord
                    Debug.Print Seek(2)
                    If Replace(MyRecord.Len_Data, Old_Word1, New_Word1) <> Null Then
                        Put #2, RecordNumber, MyRecord.Len_Data
                      Else
                        Put #2, RecordNumber, MyRecord.Len_Data
                    End If
                Next RecordNumber
                Close #2
            End If
←ここまでがわかりません。
        Next
    Next

    Set Fol = Nothing: Set FSO = Nothing
    Close #1
End Sub

よろしくお願い致します。
以上です。


引用返信 編集キー/
■2704 / inTopicNo.2)  Re[1]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ 774RR (10回)-(2007/04/13(Fri) 14:56:20)
ちゃちゃ
正直、刺身さばきたい時に、のこぎり持ってきてるような気がする
cygwin か SFU を使ってサクサクやっちゃいたい気分
http://www.atmarkit.co.jp/fwin2k/win2ktips/382sfu/sfu.html
http://journal.mycom.co.jp/special/2004/sfu/

エンコードや実体参照などを考えないで、単純置換するだけならば1行だったりする。
for i in *.html; do sed -e 's/SERVER=/CONNECTION=/g' $i > $i.substituted; done

引用返信 編集キー/
■2710 / inTopicNo.3)  Re[2]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ シャノン (126回)-(2007/04/13(Fri) 15:41:48)
シャノン さんの Web サイト
No2704 (774RR さん) に返信
> ちゃちゃ
> 正直、刺身さばきたい時に、のこぎり持ってきてるような気がする
> cygwin か SFU を使ってサクサクやっちゃいたい気分

#ちゃちゃ
Windows用のエディタ(VisualStudio含む)でも事足りるところに Unix 持ち出す方が余程…
引用返信 編集キー/
■2711 / inTopicNo.4)  Re[2]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ ぼのぼの (32回)-(2007/04/13(Fri) 15:49:40)
No2704 (774RR さん) に返信
> ちゃちゃ
> 正直、刺身さばきたい時に、のこぎり持ってきてるような気がする

まぁ↓を見るに勉強が目的みたいなので(^^;
http://bbs.wankuma.com/index.cgi?mode=al2&namber=2582#9
しかし、考えてみると、何故今からVB6を勉強したいのかってのも気になるとこですが。
開発環境が無いってことなら、VB2005 Express Editionなら無償で入手できますし。

本題に関しては、何がわからないのかわからない、というのが正直な所感ですが、
とりあえずぱっと見気になるとこが2箇所。

> For RecordNumber = 1 To 999

無条件に999回ループさせてるのは何のため?

> If Replace(MyRecord.Len_Data, Old_Word1, New_Word1) <> Null Then
>     Put #2, RecordNumber, MyRecord.Len_Data
> Else
>     Put #2, RecordNumber, MyRecord.Len_Data
> End If

IfブロックとElseブロックの内容が同じ。これぢゃIfの意味ない。

引用返信 編集キー/
■2713 / inTopicNo.5)  Re[3]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ 774RR (11回)-(2007/04/13(Fri) 16:14:41)
# さらにちゃちゃ
処理を自動化したいって話だったような気がするけど
ふつーのエディタって、ユーザの操作なしに置換して自動保存するってできるんだっけ?
しかもファイル名を変えて...

# IDE 世代の人って sed や awk や m4 なしでプログラム書いてるのか。
# 俺的にはありえんなー
引用返信 編集キー/
■2715 / inTopicNo.6)  Re[4]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ シャノン (127回)-(2007/04/13(Fri) 17:09:22)
シャノン さんの Web サイト
2007/04/13(Fri) 17:33:44 編集(投稿者)

#ニッポンチャチャチャ(謎

No2713 (774RR さん) に返信
> ふつーのエディタって、ユーザの操作なしに置換して自動保存するってできるんだっけ?

「ユーザの操作なしに」ってどういうこと?
VisualStudio 2005なら、1個置換するごとに「次を検索」っていう操作なら要らないよ。
grep しながら置換してくれる。
自動保存もできるし、自動で保存しないこともできる。

> しかもファイル名を変えて...

ファイル名を変えるっていう要求は無いはずだけど。

> # IDE 世代の人って sed や awk や m4 なしでプログラム書いてるのか。

IDE 世代って言うか Windows 世代?
どれも Windows には標準で付いてないしね。
引用返信 編集キー/
■2720 / inTopicNo.7)  Re[5]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ ろん (9回)-(2007/04/13(Fri) 17:39:11)
皆様

回答ありがとうございます。
そもそもVB6というのが、レガシーですか・・。

環境によって選ぶものが違うのも問題ですし
VB自体古いようですね。

今までVBAのみ使っていた者でして
PCに入っているVB(昔導入したVB6)で
手っ取り早く(手間取ってますが)exe ファイルを
作ってみようと思い立ったのが経緯です。

ほのぼの様
999回ループさしているのは
それぐらいの行数があれば、処理できるだろうと
安易な考えからです。

IFの両ブロックの処理が同じなのは、”Replace”が
何を返すかわからず、該当があれば置き換え、ないなら
そのまま上書きでいいか・・というこれまた安易な考えです。

中途半端なサンプルで申し訳ありません。
よろしくお願い致します。



引用返信 編集キー/
■2721 / inTopicNo.8)  Re[6]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ ろん (10回)-(2007/04/13(Fri) 18:00:23)
No2720 (ろん さん) に返信

皆様
お騒がせしたようで、申し訳ありません。
VB6以前のカテゴリがあったので
質問させていただきました。

ありがとうございました。
また利用させて頂きます。

以上です。
解決済み
引用返信 編集キー/
■2723 / inTopicNo.9)  Re[7]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ ぼのぼの (33回)-(2007/04/13(Fri) 18:54:40)
ありゃ?閉じちゃっていいんですか?
レスがつかないのは多分質問のしかたが悪いだけ
(何がわからないのかがわからないので回答しようがない)
で、VB6だからではないと思うんですけども。

もし「せっかくだからVB2005 Express Editionを使ってVB.NETでチャレンジ」
という理由で閉じるなら止めはしませんが、そうでないなら勿体ない気も…

VB6は確かにIDEとしてはレガシになりつつありますが、
業務系ではまだ現役な部分もあるでしょうし、
単純なファイル操作や文字列操作ならほぼ同じコードで動くであろう
Excel VBAは私もときどき使ってゐます。
解決済み
引用返信 編集キー/
■2731 / inTopicNo.10)  Re[8]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ Jitta (301回)-(2007/04/13(Fri) 20:51:21)
No2723 (ぼのぼの さん) に返信
> ありゃ?閉じちゃっていいんですか?

同感
解決済み
引用返信 編集キー/
■2744 / inTopicNo.11)  Re[9]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ Hirotow (81回)-(2007/04/14(Sat) 15:41:24)
Hirotow さんの Web サイト
既出ですが、どうせならVB.NETやC#に移行してみては。
#ちなみにインストールするときはISOイメージよりWebセットアップのほうが若干速いです。

蛇足までにVB.NETだと、
Imports System
Imports System.IO
Imports System.Text.Regex

Namespace Replace
	Class Program
		Public Shared Sub ReplaceInDirectory(ByVal dir As String, ByVal pat As String, ByVal old As String, ByVal dest As String, ByVal rec As Boolean, ByVal backup As Boolean)
			'正規表現を生成
			Dim rex As New Regex(pat)

			'すべてのファイルを反復処理
			Dim files As String() = Directory.GetFiles(dir)
			For Each file As String In files
				'正規表現に一致するならば
				If rex.IsMatch(Path.GetFileName(file)) Then
					'一時ファイルと予備ファイルのファイル名を生成
					Dim tmp As String = file + ".tmp"
					Dim bak As String = file + ".bak"

					'対象ファイルを開く
					Using sr As New StreamReader(file)
						'一時ファイルを開く
						Using sw As streamWriter = New StreamWriter(tmp)
							'ファイルの終端まで
							While sr.EndOfStream
								'対象ファイルから次の行を読み込み
								Dim line As String = sr.ReadLine()
								'読み込んだ行を置換
								line = line.Replace(old, dest)
								'置換した行を一時ファイルに書き込み
								sw.WriteLine(line)
							End While

							'各ファイルを閉じる
							sr.Close()
							sw.Close()
						End Using
					End Using

					'バックアップを保存
					If backup Then
						File.Move(file, bak)
					End If
					'対象ファイルに一時ファイルを上書き
					File.Move(tmp, file)
				End If
			Next

			'再帰処理
			If rec Then
				'すべてのサブディレクトリを反復処理
				Dim subdirs As String() = Directory.GetDirectories(dir)
				For Each subdir As String In subdirs
					ReplaceInDirectory(subdir, pat, old, dest, rec, backup)
				Next
			End If
		End Sub

		<STAThread()> _
		Public Shared Sub Main(ByVal args As String())
			Dim old As String = "SERVER="
			Dim dest As String = "CONNECTION="
			Dim dir As String = "C:\apps\"

			ReplaceInDirectory(old, "\.txt$", old, dest, False, False)
		End Sub
	End Class
End Namespace

みたいになります。

解決済み
引用返信 編集キー/
■2780 / inTopicNo.12)  Re[10]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ ろん (11回)-(2007/04/16(Mon) 14:37:02)
No2744 (Hirotow さん) に返信

Hirotow 様
Jitta 様
ぼのぼの様

 なかなか面倒な質問にご連絡頂き、大変うれしく思います。

 ※.Net のソース、ありがとうございます。
  VBとこんなにも違うものなのですね!!
  使いこなすとなると・・かなり勉強しなければなりません。

 こちらを閉じさせて頂きました後、VBA系のサイトに
 助けを求め、あとは自力で整えてなんとか形になってまいりました。

 他のサイトに質問をさせて頂いておりますので
 こちらで継続して教えて頂くのは、多くの方に失礼かと存じますので
 現状をご説明させて頂きます。

【やりたいこと】
 これは、頭書の記載と変わりありません。

【残っている問題】
テキストファイルのデータ長(行の長さ)が可変であるため
正しく1行毎に読み込めていないため、正しく置き換えができていない箇所がある
という問題が残っております。
あとは、機能的にはうまくいっているようです。

以下に現状のソースを転載いたします。

Public Const Old_Word1 = "SERVER="
Public Const New_Word1 = "CONNECTION="
Public Const Out_Dir = "C:\apps\"
Public Const Out_Log = "STRING_CONV.log"
Option Compare Text

Type Record
Len_Data As String * 80
End Type
'
'
'
Sub Main()
Dim Out_SubDir As String
Dim WK_Msg As String
Dim FSO As Object, Fol As Object, MyFol As Object
Dim MyFile As Object
Dim OutFile As String
Dim hFso As FileSystemObject
Set hFso = New FileSystemObject
Dim Cnt_Line As Integer
Dim MyRecord As Record, RecordNumber
ChDir Out_Dir
Open Out_Log For Output As #1
Write #1, Now(), "STRING CONVERSION START"

Set FSO = CreateObject("Scripting.FileSystemObject")
Set Fol = FSO.GetFolder(Out_Dir)
For Each MyFol In Fol.SubFolders
Out_SubDir = Out_Dir & MyFol.Name
Write #1,
Write #1, Now(), "Folder = " & Out_SubDir

For Each MyFile In MyFol.Files
If MyFile.Name Like "*.ACX" Then
Out_File = Out_SubDir & "\" & MyFile.Name
Open Out_File For Random As #2 Len = Len(MyRecord)

RecordNumber = 1
Do While Not EOF(2)
Get #2, RecordNumber, MyRecord
Debug.Print Seek(2)
If InStr(1, MyRecord.Len_Data, Old_Word1) <> 0 Then
str1 = Replace(MyRecord.Len_Data, Old_Word1, New_Word1)
MyRecord.Len_Data = str1
Put #2, RecordNumber, MyRecord.Len_Data
Write #1, Now(), "File = " & Out_File, "Conv Rule1 = " & Seek(2) - 1,
End If
RecordNumber = RecordNumber + 1
Loop
Close #2
End If
Next
Next

Set hFso = Nothing
Set Fol = Nothing: Set FSO = Nothing
Close #1
End Sub

皆様ご丁寧にありがとうございます。
以上です。
引用返信 編集キー/
■2787 / inTopicNo.13)  Re[11]: フォルダ内のテキストファイルの文字列を変換する方法2
□投稿者/ ろん (12回)-(2007/04/16(Mon) 16:33:50)
No2780 (ろん さん) に返信

皆様

 お騒がせ致しました。
 なんとか、思ったものが出来ました。

 Random で読むと 可変長のファイルに対して
 ハンドリングできないようで
 別ファイルに書き出して処理を行うように
 変更いたしました。

 ありがとうございました。
 また利用させていただきたいと思います。
 以上です。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -