その他

複数行のテキストファイルを1行にする。bat、vbs(Scripting.FileSystemObject、ADODB.Stream)[No41]

スポンサーリンク

今回は、複数行あるテキストファイルを読み込んで、別の新しいファイルに1行に変換して出力するプログラムを紹介します。

ここでは次の3種類の実行ファイルを用いた方法を紹介しますが、おすすめは3番目の方法です。文字化けせず、きちんと出力されます。

  1. batファイル(Windows Shell)
  2. vbsファイル(VBScript:Scripting.FileSystemObject使用)
  3. vbsファイル(VBScript:ADODB.Stream使用)

記事用のInputファイルについて

今回は複数行のテキストとして、次のファイル「bookmarks_YYYY_MM_DD.html」を利用します。(ここでは保存時はUTF-8とします。)


<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
     It will be read and overwritten.
     DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>
    <DT><H3 ADD_DATE="" LAST_MODIFIED="" PERSONAL_TOOLBAR_FOLDER="true">ブックマーク バー</H3>
    <DL><p>
        <DT><A HREF="https://www.yahoo.co.jp/" ADD_DATE="" ICON="">サイト1</A>
        <DT><A HREF="https://www.yahoo.co.jp/" ADD_DATE="" ICON="">サイト2</A>
        <DT><A HREF="https://www.yahoo.co.jp/" ADD_DATE="" ICON="">サイト3</A>
    </DL><p>
</DL><p>

手順

今回利用するファイル「bookmarks_YYYY_MM_DD.html」は「ブックマークをエクスポート」で入手することができます。手順は以下の通りです。

1.Google Chromeで「Yahoo! JAPAN」をブックマーク(Bookmark)に3つ登録し、名前を変更する。

2.ブックマーク→「ブックマークマネージャ」を開く。

3.「・・・」のハンガーバーをクリックする。

4.「ブックマークをエクスポート」を押して保存場所に保存する。

準備

適当な場所に新しいフォルダを作成し、その中に先程手順に従って入手したファイル「bookmarks_YYYY_MM_DD.html」と”以下で詳細する実行ファイル”を置きます。

スポンサーリンク

1.batファイル(Windows Shell)の場合


@echo off
echo ----------------------------------------
for %%i in (.\bookmarks_*.html) do (
rem 入力ファイル
	set inputfile=%%i
	echo 「ファイル名」: %%i
)
rem 出力ファイル
set outputfile=.\workfile1.html
chcp 65001
call :changeOneLine > %outputfile%
exit /b

rem ファイルの中身を1行にするサブルーチン
:changeOneLine
for /f "delims=" %%A in (%inputfile%) do (set /p = "%%A" <NUL)
exit /b

実行結果

補足

下図のように「/?」がある場合は、

次のような長文のテキストが出力されます。このことについては下記リンク先の記事に詳しく書いてあります。

no image
コマンドプロンプト、batファイルの実行結果に謎の長文のテキストが出力されるのは何故?[No40]
バッチファイルを作成していたら、何故か謎の長文の文章が出力されてしまいました。いきなり身に覚えのない長文テキストが表示されると、何事かと焦りますよね。私と同じような体験をした人もいる ...

スポンサーリンク

2.vbsファイル(VBScript:Scripting.FileSystemObject使用)の場合


'------------------------------------------------------------------------
'定数定義
'------------------------------------------------------------------------
Dim filenameIn   : filenameIn   = "bookmarks_"
Dim extensionIn  : extensionIn  = ".html"

Dim filenameOut  : filenameOut  = "workfile1"
Dim extensionOut : extensionOut = ".html"
'------------------------------------------------------------------------
'カレントディレクトリのパス
'------------------------------------------------------------------------
Dim Obj00 : Set Obj00 = WScript.CreateObject("Scripting.FileSystemObject")
Dim var00 : var00     = Obj00.getParentFolderName(WScript.ScriptFullName)
'------------------------------------------------------------------------
'01:Inputファイルのパスを取得する
'------------------------------------------------------------------------
Dim Obj01     : Set Obj01     = CreateObject("Scripting.FilesystemObject")
Dim ObjFolder : Set ObjFolder = Obj01.getFolder(var00)
Dim ObjFiles  : Set ObjFiles  = ObjFolder.Files

Dim TempFileName
For Each TempFileName In ObjFiles
	If Right(TempFileName.Name,Len(extensionIn)) = extensionIn Then
		If Left(TempFileName.Name,Len(filenameIn)) = filenameIn Then
			Dim filePathIn  : filePathIn = TempFileName.Path
			Dim filePathOut : filePathOut = var00 & "\" & filenameOut & extensionOut
			Exit For
		Else
			MsgBox("The target file does not exist.")
			Set Obj01 = Nothing
			WScript.Quit
		End If
	End If
Next
Set Obj01     = Nothing
Set ObjFolder = Nothing
Set ObjFiles  = Nothing
'------------------------------------------------------------------------
'02:Inputファイルを読み込む
'------------------------------------------------------------------------
'OpenTextFile : https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/opentextfile-method
Dim Obj0201 : Set Obj0201 = WScript.CreateObject("Scripting.FileSystemObject")
Dim Obj0202 : Set Obj0202 = Obj0201.OpenTextFile(filePathIn,,,TristateFalse) 'OpenTextFile(filename,[iomode,[create,[format]]])
Dim TempTextBefore : TempTextBefore = Obj0202.ReadAll
Obj0202.Close
Set Obj0201 = Nothing
Set Obj0202 = Nothing
'------------------------------------------------------------------------
'文字列の置換
'------------------------------------------------------------------------
Dim TempTextAfter  : TempTextAfter  = Replace(TempTextBefore,vbCrLf,"")
'------------------------------------------------------------------------
'03:Outファイルを作成する
'------------------------------------------------------------------------
'CreateTextFile : https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/createtextfile-method
Dim Obj0301 : Set Obj0301 = WScript.CreateObject("Scripting.FileSystemObject")
Dim Obj0302 : Set Obj0302 = Obj0301.CreateTextFile(filePathOut,True,True) 'CreateTextFile(filename,[overwrite,[unicode]])
Obj0302.Close
Set Obj0301 = Nothing
Set Obj0302 = Nothing
'------------------------------------------------------------------------
'04:Outファイルに追記する
'------------------------------------------------------------------------
'TextStream オブジェクト : https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/textstream-object
'Write メソッド          : https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/write-method
'WriteLine メソッド      : https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/writeline-method
Dim Obj0401 : Set Obj0401 = WScript.CreateObject("Scripting.FileSystemObject") 
Dim Obj0402 : Set Obj0402 = Obj0401.OpenTextFile(filePathOut,8,True) '2の場合上書き、8の場合追記
Obj0402.WriteLine(TempTextAfter) 'Writeの場合:改行なし、Writelineの場合:改行あり
Obj0402.Close
Set Obj0401 = Nothing
Set Obj0402 = Nothing

実行結果

次の画像のように文字化けしてしまいます。ScriptingFileSystemObjectはUTF-8の文字コードを上手く扱えないことが原因です。

スポンサーリンク

3.vbsファイル(VBScript:ADODB.Stream使用)の場合


'------------------------------------------------------------------------
'定数定義
'------------------------------------------------------------------------
Dim filenameIn   : filenameIn   = "bookmarks_"
Dim extensionIn  : extensionIn  = ".html"

Dim filenameOut  : filenameOut  = "workfile1"
Dim extensionOut : extensionOut = ".html"
'------------------------------------------------------------------------
'カレントディレクトリのパス
'------------------------------------------------------------------------
Dim Obj00 : Set Obj00 = WScript.CreateObject("Scripting.FileSystemObject")
Dim var00 : var00     = Obj00.getParentFolderName(WScript.ScriptFullName)
'------------------------------------------------------------------------
'01:Inputファイルのパスを取得する
'------------------------------------------------------------------------
Dim Obj01     : Set Obj01     = CreateObject("Scripting.FilesystemObject")
Dim ObjFolder : Set ObjFolder = Obj01.getFolder(var00)
Dim ObjFiles  : Set ObjFiles  = ObjFolder.Files

Dim TempFileName
For Each TempFileName In ObjFiles
	If Right(TempFileName.Name,Len(extensionIn)) = extensionIn Then
		If Left(TempFileName.Name,Len(filenameIn)) = filenameIn Then
			Dim filePathIn  : filePathIn = TempFileName.Path
			Dim filePathOut : filePathOut = var00 & "\" & filenameOut & extensionOut
			Exit For
		Else
			MsgBox("The target file does not exist.")
			Set Obj01 = Nothing
			WScript.Quit
		End If
	End If
Next
Set Obj01     = Nothing
Set ObjFolder = Nothing
Set ObjFiles  = Nothing
'------------------------------------------------------------------------
'02:Inputファイルを読み込む
'------------------------------------------------------------------------
'Stream オブジェクト : https://docs.microsoft.com/ja-jp/sql/ado/reference/ado-api/stream-object-properties-methods-and-events?view=sql-server-ver15
Dim Obj0201 : Set Obj0201 = CreateObject("ADODB.Stream")
With Obj0201
	.Type = 2 'adTypeText
	.Charset = "UTF-8"
	.Open
	.LoadFromFile filePathIn
End With

Dim TempTextBefore : TempTextBefore = Obj0201.ReadText(-1) 'adReadAll
Obj0201.Close
Set Obj0201 = Nothing
'------------------------------------------------------------------------
'文字列の置換
'------------------------------------------------------------------------
Dim TempTextAfter
TempTextAfter  = Replace(TempTextBefore,vbCrLf,"")
'------------------------------------------------------------------------
'03:Outファイルを作成する
'------------------------------------------------------------------------
'CreateTextFile : https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/createtextfile-method
Dim Obj0301 : Set Obj0301 = WScript.CreateObject("Scripting.FileSystemObject")
Dim Obj0302 : Set Obj0302 = Obj0301.CreateTextFile(filePathOut,True,True) 'CreateTextFile(filename,[overwrite,[unicode]])
Obj0302.Close
Set Obj0301 = Nothing
Set Obj0302 = Nothing
'------------------------------------------------------------------------
'04:Outファイルに追記する
'------------------------------------------------------------------------
'Stream オブジェクト : https://docs.microsoft.com/ja-jp/sql/ado/reference/ado-api/stream-object-properties-methods-and-events?view=sql-server-ver15
Dim Obj04 : Set Obj04 = CreateObject("ADODB.Stream")

With Obj04
	.Mode = 3 'adModeReadWrite
	.Type = 2 'adTypeText
	.Charset = "UTF-8"
	.Open
	.WriteText TempTextAfter,0 'adWriteChar
	.SaveToFile filePathOut,2 'adSaveCreateOverWrite
End With

Obj04.Close
Set Obj04 = Nothing

実行結果

このままではインデントがそのまま残ってしまいます。

スポンサーリンク

インデント対策後


'------------------------------------------------------------------------
'定数定義
'------------------------------------------------------------------------
Dim filenameIn   : filenameIn   = "bookmarks_"
Dim extensionIn  : extensionIn  = ".html"

Dim filenameOut  : filenameOut  = "workfile1"
Dim extensionOut : extensionOut = ".html"
'------------------------------------------------------------------------
'カレントディレクトリのパス
'------------------------------------------------------------------------
Dim Obj00 : Set Obj00 = WScript.CreateObject("Scripting.FileSystemObject")
Dim var00 : var00     = Obj00.getParentFolderName(WScript.ScriptFullName)
'------------------------------------------------------------------------
'01:Inputファイルのパスを取得する
'------------------------------------------------------------------------
Dim Obj01     : Set Obj01     = CreateObject("Scripting.FilesystemObject")
Dim ObjFolder : Set ObjFolder = Obj01.getFolder(var00)
Dim ObjFiles  : Set ObjFiles  = ObjFolder.Files

Dim TempFileName
For Each TempFileName In ObjFiles
	If Right(TempFileName.Name,Len(extensionIn)) = extensionIn Then
		If Left(TempFileName.Name,Len(filenameIn)) = filenameIn Then
			Dim filePathIn  : filePathIn = TempFileName.Path
			Dim filePathOut : filePathOut = var00 & "\" & filenameOut & extensionOut
			Exit For
		Else
			MsgBox("The target file does not exist.")
			Set Obj01 = Nothing
			WScript.Quit
		End If
	End If
Next
Set Obj01     = Nothing
Set ObjFolder = Nothing
Set ObjFiles  = Nothing
'------------------------------------------------------------------------
'02:Inputファイルを読み込む
'------------------------------------------------------------------------
'Stream オブジェクト : https://docs.microsoft.com/ja-jp/sql/ado/reference/ado-api/stream-object-properties-methods-and-events?view=sql-server-ver15
Dim Obj0201 : Set Obj0201 = CreateObject("ADODB.Stream")
With Obj0201
	.Type = 2 'adTypeText
	.Charset = "UTF-8"
	.Open
	.LoadFromFile filePathIn
End With

Dim TempTextBefore : TempTextBefore = Obj0201.ReadText(-1) 'adReadAll
Obj0201.Close
Set Obj0201 = Nothing
'------------------------------------------------------------------------
'文字列の置換
'------------------------------------------------------------------------
Dim regEx : Set regEx = New RegExp
With regEx
   .Pattern = "^[ \t]+"
   .IgnoreCase = True
   .Global = True
   .MultiLine = True
End With

Dim TempTextAfter
TempTextAfter = regEx.Replace(TempTextBefore, "")
TempTextAfter  = Replace(TempTextAfter,vbCrLf,"")
'------------------------------------------------------------------------
'03:Outファイルを作成する
'------------------------------------------------------------------------
'CreateTextFile : https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/createtextfile-method
Dim Obj0301 : Set Obj0301 = WScript.CreateObject("Scripting.FileSystemObject")
Dim Obj0302 : Set Obj0302 = Obj0301.CreateTextFile(filePathOut,True,True) 'CreateTextFile(filename,[overwrite,[unicode]])
Obj0302.Close
Set Obj0301 = Nothing
Set Obj0302 = Nothing
'------------------------------------------------------------------------
'04:Outファイルに追記する
'------------------------------------------------------------------------
'Stream オブジェクト : https://docs.microsoft.com/ja-jp/sql/ado/reference/ado-api/stream-object-properties-methods-and-events?view=sql-server-ver15
Dim Obj04 : Set Obj04 = CreateObject("ADODB.Stream")

With Obj04
	.Mode = 3 'adModeReadWrite
	.Type = 2 'adTypeText
	.Charset = "UTF-8"
	.Open
	.WriteText TempTextAfter,0 'adWriteChar
	.SaveToFile filePathOut,2 'adSaveCreateOverWrite
End With

Obj04.Close
Set Obj04 = Nothing

インデント対策を施した後のプログラムの結果がこちらです。

注意

実行環境によって改行コードが変わるので、実行結果も異なります。この記事に書かれている内容は、すべてWindowsを実行環境とした場合の話です。

参考サイト

MicrosoftのVBScript.RegExpのページにMultiLineの記述がない [VBScript] : スクリプトちょっとメモ

正規表現のオプション | Microsoft Docs

雑記

皆さんは東京都立川市にある国営昭和記念公園をご存知でしょうか。

毎年開花場所が変わるのですが、今年は「ハーブの丘」にサンフィニティという品種のヒマワリが咲いています。一般的なヒマワリと違い、草丈は50cmから120cmほどと低く、花径8cmほどの小さめのヒマワリです。

広大な敷地に咲くおよそ2千本ものヒマワリを、子どもからお年寄りまで自由に楽しむことができるのは素敵ですよね。

また、「原っぱ西花畑」と呼ばれるエリアには、およそ5万本のハイブリッドサンフラワーという品種のヒマワリが咲いています。草丈約150cmと背が高く、花径も30cmほどある大輪花で見応えがあります。西花畑園路内にヒマワリを一望できるお立ち台が設置してあるので、辺り一面に咲くヒマワリが太陽に照らされて輝く様子を堪能することができます。

今がちょうど見頃なので、お近くの方は是非ヒマワリ畑で夏を感じてみて下さい。

最後までお付き合いいただきありがとうございます!

この情報が誰かの役にたてれば幸いです。

スポンサーリンク

-その他