忍者ブログ

テキストファイルから指定した文字列を含む行を抽出するVBScript

2021年04月24日

ログファイルからハードウェア故障の有無を調べることがある。

何度も何度もキーワードを変えて検索を繰り返すのはくそだりぃので
該当の文字列を含む行だけ抽出するVBScriptを作ってみた。



簡単にできるだろと高を括っていたけど、意外にも苦戦。
なんとか想定した2時間で完成。

ん・・・。
ログファイルってUTF8の可能性もあるよな。。。

で、作り直し。


VBScriptでUTF8のファイル読み込みで検索したら、神がかったサイトを発見。
https://neos21.net/blog/2016/03/25-01.html

UTF-8 テキストを読み込み、同じ内容をUTF-8テキストで書き込むサンプル。

読み込みと書き込みの間に文字列を比較する処理を追加して完成。

趣味プログラミングでは、流用しやすいソースを見つけられるかで全然工数が違う。
自分でVBAで同じようなことやったのに、ググった方が早いだなんて。。。



◆使用方法◆
ソースをメモ帳にコピーし、「.vbs」形式で保存。
ログファイルを保存したファイルのアイコンにドラッグドロップする。
(複数ファイルにも対応)
ログファイルの文字コードに合わせて設定を変えなきゃいけないのはめんどいな。


以下、ソース。




Option Explicit
'テキストファイルから指定した文字列を含む行を抽出するVBScript

'-----------------------------------------------------------オプション設定ここから
'ログファイルの文字コードを指定
'const strCode = "UTF-8" ' 文字コード指定 "Shift-Jis" "UTF-8"
const strCode = "Shift-Jis" ' 文字コード指定 "Shift-Jis" "UTF-8"

'キーワードと検索モード if Instr(1,lineStr,KeyWord1,cMode) > 0
const KeyWord1 = "文字列1"
const KeyWord2 = "文字列2"
const KeyWord3 = "Ui"
const cMode = 1 '0:バイナリ 1:テキスト ※バイナリだと大文字と小文字を区別
'Instr関数は、文字列を検索して位置を返す。なければ0を返す。開始位置を指定しないとモード指定できない

'-----------------------------------------------------------オプション設定ここまで

'ドラッグドロップでファイルを印刷するスクリプト
'http://chuckischarles.hatenablog.com/entry/2018/10/29/002921
'ファイル名の末尾に更新日時を付与するVBScript
'http://gren-dken.hatenablog.com/entry/2013/08/22/000119
'-------------------------------------------------------------------------------------------------------
' 引数が無かった時の処理
If WScript.Arguments.count = 0 then
WScript.Echo "引数が無いため、実行できません。" & vbNewLine & _
"ファイルをドロップしてください。"
WScript.Quit
End If

dim targetPath,changePath
dim FSO
'----------------------------------------------------------------------------------------------------
' ファイルシステムオブジェクト作成
Set FSO = CreateObject("Scripting.FileSystemObject")
'-------------------------------------------------------------------------------------------------------
' フォルダ内ファイルリスト出力
for each targetPath In WScript.Arguments
'----------------------------------------------------------------------------------------------------
' ドロップされた引数がフォルダかファイルかを判定する
If FSO.FolderExists(targetPath) then
' is folder.
WScript.Echo "フォルダがドロップされました。" & vbNewLine & _
"処理を終了します。"
WScript.Quit
ElseIf FSO.FileExists(targetPath) then
' is file.
else
' is unknown.
WScript.Echo "フォルダ 及び ファイル とも認識できないデータがドロップされました。" & vbNewLine & _
"処理を終了します。"
WScript.Quit
End If
' メインモジュール呼び出し
Call TextFilterMain(targetPath)
Next
set FSO = nothing

WScript.Quit 'メイン処理終了

'-----------------------------------------------------------実質ここから

Sub TextFilterMain(targetPath)

'https://neos21.net/blog/2016/03/25-01.htmlをもろパクリ

dim outputPath :outputPath = createOutputFilePath( targetPath ) '出力ファイルフルネーム
Dim strLine'入力用バッファ
dim oBuf '出力用バッファ

' 読み込みファイルの指定 (相対パスなのでこのスクリプトと同じフォルダに置いておくこと)
Dim input
Set input = CreateObject("ADODB.Stream")
input.Type = 2 ' 1:バイナリ・2:テキスト
input.Charset = strCode ' 文字コード指定
input.Open ' Stream オブジェクトを開く
input.LoadFromFile targetPath ' ファイルを読み込む

' 書き出しファイルの指定 (今回は新規作成する)
Dim output: Set output = CreateObject("ADODB.Stream")
output.Type = 2
output.Charset = strCode
output.Open

' 読み込みファイルから1行ずつ読み込み、書き出しファイルに書き出すのを最終行まで繰り返す
Dim records
Dim lineStr
Do Until input.EOS
lineStr = input.ReadText(-2) ' -1:全行読み込み・-2:一行読み込み
'◆文字列フィルタ処理◆
if Instr(1,lineStr,KeyWord1,cMode) > 0 or Instr(1,lineStr,KeyWord2,cMode) > 0 or Instr(1,lineStr,KeyWord3,cMode) > 0 then
output.WriteText lineStr, 1 ' 0:文字列のみ書き込み・1:文字列 + 改行を書き込み
end if
Loop '読み込みながら書き込みは重いかも・・・

' 書き出しファイルの保存
output.SaveToFile outputPath, 2 '1:指定ファイルがなければ新規作成・2:ファイルがある場合は上書き

' Stream を閉じる
input.Close
output.Close

'ログファイルを開く
call OpenTextFileShell(outputPath)
End Sub

'------------------------------
' 出力ファイル名の生成
'------------------------------
Function createOutputFilePath(targetPath )
const strHead = "■" 'ファイル名の先頭につける文字
const strFoot = "解析結果" 'ファイル名のお尻につける文字

dim fo: Set fo = FSO.GetFile(targetPath) 'FSOはグローバルで宣言
' ファイルパス分割
Dim targetDir: targetDir = FSO.GetParentFolderName(targetPath)
Dim targetBaseName: targetBaseName = FSO.GetBaseName(targetPath)
Dim targetExt: targetExt = FSO.GetExtensionName(targetPath)

' 変更後ファイルパス生成し、返却
createOutputFilePath = targetDir & "\" & strHead & targetBaseName & "_" & strFoot & "." & targetExt
End Function

'------------------------------
' CMDで指定したファイルを開く
'------------------------------
sub OpenTextFileShell(FulName)

Dim objWshShell
'シェルオブジェクトの作成
Set objWshShell = WScript.CreateObject("WScript.Shell")
'シェルの実行
objWshShell.Run FulName

end sub

続編で一般化してみた。
テキストファイルから指定した文字列を含む行を抽出するVBScriptの一般化

PR
Comment
  Vodafone絵文字 i-mode絵文字 Ezweb絵文字