行頭行末の不要スペースを削除する方法

IT作業員Tipsシリーズ!

いつもお世話になっております。
RfromL.comです。

今回はファイル内各行の行頭、行末に不要なスペース(全角・半角いずれも)が存在している場合にスペースだけを削除する方法についてです。

TABLE OF CONTENTS

1.はじめに
2.テキストエディタ(コマンド)で削除
3.テキストエディタ(正規表現)で削除
4.バッチスクリプト(引数指定)で削除
5.バッチスクリプト(リテラル指定)で削除
6.おわりに


1.はじめに

あるファイル内において1行(レコード)単位で行頭や、行末に不要なスペース(半角または全角)が含まれてた場合にファイル内から不要なスペースを削除する方法です。

方法としては以下の3種類で削除します。
①テキストエディタで開いてコマンドで削除
②テキストエディタで開いて正規表現で削除
③バッチスクリプト+VBSで削除

①と②のテキストエディタでの方法は、本投稿ではサクラエディタを使用しています。
※②の方法は正規表現が使用できれば他のテキストエディタでもできますが、①の方法は、他のエディタではコマンドが異なる可能性があるので、各エディタのヘルプで確認してみてください。

③のバッチスクリプト+VBSでの削除には、いつものごとく入出力ファイルを引数で指定する場合と、リテラル(固定値)で指定する場合の2パターンを記載しています。


2.テキストエディタ(コマンド)で削除

2.1.手順

① 行頭行末からスペースを削除したいファイル をサクラエディタで開きます。



②「CTRL」キー + 「A」キーでファイル内を全選択します。



③「ALT」キー + 「L」キーで行頭のスペース(半角全角両方)を削除します。



④「ALT」キー + 「R」キーで行末のスペース(半角全角両方)を削除します。

ここまでで行頭行末のスペースは削除できていますが、スペースしかなかった行は改行コードのみの空行ができてしまっています。
空行の削除については過去の投稿「ファイルから改行のみの空レコード(空行)を削除」で使用した正規表現で削除します。


⑤正規表現で空行を削除
 ⑤-1.「CTRL」キー + 「R」キーで置換ウィンドウを表示します。
 ⑤-2.置換前の欄に「^\r\n」を、置換後の欄を「」(空欄)に設定します。

※この手順は改行コード「CRLF」の場合です。ファイルの改行コードが「CR」、「LF」の場合には以下表の通り置換前の欄に指定する値を変えてください。

改行コード正規表現
CRLF^\r\n
CR^\r
LF^\n

⑤-3.正規表現(E)のチェックをオンにして「ALT」キー + 「A」キー で全て置換を実行。


これで空行も削除されて不要なスペースも消えました。

2.2.解説

サクラエディタのLTRIM(エルトリム)コマンド、RTRIM(アールトリム)コマンドを使用して削除する方法となっています。

コマンド名入力キー処理内容
LTRIM「ALT」+「L」選択範囲内で各レコードの行頭のスペースを削除
RTRIM「ALT」+「R」選択範囲内で各レコードの行末のスペースを削除

つまりはSQLやVBSなどにある関数。「LTRIM」関数、「RTRIM」関数を実行してくれるショートカットコマンドです。

空行削除の部分については、今回のファイルが改行コード「CRLF」のみなので、正規表現で「行頭に位置するCRLF改行コード」に一致するパターンを指定して置換で削除しています。
詳細は過去記事「ファイルから改行のみの空レコード(空行)を削除」 で書いています。


3.テキストエディタ(正規表現)で削除

3.1.手順

①行頭行末からスペースを削除したいファイル をサクラエディタで開きます。
②「CTRL」キー + 「R」キーで置換ウィンドウを表示します。
③置換前の欄に「^\s+|\s+$」を、置換後の欄を「」(空欄)に設定します。
④正規表現(E)のチェックをオンにして「ALT」キー + 「A」キー で全て置換を実行。



上記の置換を実行することで、以下のように 行頭行末から不要なスペースが削除されます。

3.2.解説

置換前の入力欄に指定した正規表現「^\s+|\s+$」の意味は以下となります。
「行頭に位置する連続した空白類文字、または行末に位置する連続した空白類文字」に一致した文字列を検索。
この正規表現で抽出した文字列に対し、置換後の入力欄に「」(空欄)を指定し置換することで削除しています。

最終的な機能としては上記の通りですが、構成している要素としては以下の3つで出来ています。

No.正規表現説明
^\s+「^」が行頭、「\s」がスペース(半角全角)などの空白類文字、「+」が直前の指定値を1つ以上繰り返し。を意味しています。
|パターンの論理和。つまり「or 条件」を意味しています。
\s+$「\s」がスペース(半角全角)などの空白類文字、「+」が直前の指定値を1つ以上繰り返し、「$」が行末。を意味しています。

また、この正規表現で置換した結果をみると分かるとおり、スペースしかなかったレコードについては空行(改行コードのみのレコード)として残らずに削除されていますが、これは①「^\s+」の正規表現で抽出されています。

『「\s」がスペース(半角全角)などの空白類文字』と記載されている箇所の『空白類文字』には改行コードも含まれています。
空白文字類についてはサクラエディタのヘルプで以下のように記載されています。

※以下、サクラエディタのヘルプより抜粋。

\s空白類文字 [ \t\v\x0a\x0d]と同じ


空白類文字に記載されているコードをそれぞれ説明すると以下の通りです。

コード意味
\t水平タブコード
\v垂直タブコード
\x0aLF改行コード
\x0dCR改行コード

4.バッチスクリプト(引数指定)で削除

4.1.手順

①以下のバッチスクリプトとVBSを用意します。
[SpaceTrim.bat]

@echo off
@rem ------------------------------------------------------------
@rem - 行頭・行末スペース削除
@rem -
@rem - 引数1 %1
@rem - 入力ファイルパス(説明:入力ファイルパスをフルパスで設定する。)
@rem - 例:C:\RfromL_com\SpaceTrim\input\TRIM_IN.csv
@rem -
@rem - 引数2 %2
@rem - 出力ファイルパス(説明:出力ファイルパスをフルパスで設定する。)
@rem - 例:C:\RfromL_com\SpaceTrim\output\TRIM_OUT.csv
@rem -
@rem ------------------------------------------------------------
@rem - 初期処理
@rem ------------------------------------------------------------
:STEP000

@rem カレントディレクトリ設定
set  CMD_PATH=%~dp0

@rem ------------------------------------------------------------
@rem - ファイル設定
@rem ------------------------------------------------------------
:STEP010
@rem ファイルID設定(引数取得)
set  IFILE001=%1
set  OFILE001=%2

@rem ------------------------------------------------------------
@rem - 引数チェック
@rem ------------------------------------------------------------
:STEP020
@rem 引数1
if "%1%"=="" (
  echo 引数1:入力ファイルパスが指定されていません
  goto ABEND
)

@rem 引数2
if "%2%"=="" (
  echo 引数2:出力ファイルパスが指定されていません
  goto ABEND
)

@rem ------------------------------------------------------------
@rem - TRIM処理
@rem ------------------------------------------------------------
:STEP030
@rem ファイル内のレコード毎に行頭・行末スペース(半角・全角)を削除
cscript //nologo %CMD_PATH%\SpaceTrim.vbs %IFILE001% %OFILE001%

@rem ------------------------------------------------------------
@rem - 終了処理
@rem ------------------------------------------------------------
:END

exit 0

@rem ------------------------------------------------------------
@rem - 異常終了処理
@rem ------------------------------------------------------------
:ABEND

exit 9



[SpaceTrim.vbs]

Option Explicit
' * -----------------------------------------------------------
' * システム名         : RfromL.com
' * 処理名             : TRIM処理
' * 処理内容           : 入力ファイルからレコードを読込み
' *                      行頭・行末のスペース(半角、全角)を
' *                      削除して出力ファイルに書き込みを行う。
' *                      Trimした結果、空レコードだった場合は
' *                      出力対象外とする。
' * 作成日             : 2021.09.22
' * 作成者             : RfromL.com
' * パラメータ         : 0:InFile  (入力ファイルフルパス)
' *                      1:OutFile (入力ファイルフルパス)
' * 備考               : 入力チェックなし
' * 
' * *** 修正履歴 **********************************************
' * No.  日付        修正者              内容
' * 001  2021.09.22  RfromL.com          新規作成
' * 
' * -----------------------------------------------------------
' -------------------------------------------------------------
' 変数の宣言&情報の取得
' -------------------------------------------------------------
Dim objArgs        ' 引数
Dim objFS          ' ファイルシステムオブジェクト
Dim objIText       ' 入力ファイル用
Dim objOText       ' 出力ファイル用

Dim in_Cnt         ' 入力ファイル件数カウンタ
Dim out_Cnt        ' 出力ファイル件数カウンタ
Dim nul_Cnt        ' 空レコード件数カウンタ

Dim argITextFile   ' 引数①(入力ファイルパス)格納用
Dim argOTextFile   ' 引数②(出力ファイルパス)格納用

Dim strReadLine    ' 入力レコード格納用
Dim strWriteLine   ' 出力レコード格納用

' -------------------------------------------------------------
' 引数取得
' -------------------------------------------------------------
' 入出力ファイル設定(フルパス指定)
Set objArgs = WScript.Arguments
argITextFile = objArgs(0) '第1引数 入力ファイルパス
argOTextFile = objArgs(1) '第2引数 出力ファイルパス

' -------------------------------------------------------------
' 前処理
' -------------------------------------------------------------
' ファイルシステムオブジェクトの生成
Set objFS = CreateObject("Scripting.FileSystemObject")

' 入力ファイルOPEN (1:読み取り専用でファイルオープン)
Set objIText = objFS.OpenTextFile(argITextFile,1)

' 出力ファイル作成 (True:上書き指定でファイル新規作成)
set objOText = objFS.createtextfile(argOTextFile,True)

' -------------------------------------------------------------
' 開始処理
' -------------------------------------------------------------
' 処理開始
WScript.Echo "START"

' -------------------------------------------------------------
' メイン処理
' -------------------------------------------------------------
' 初期値セット
in_Cnt = 0       ' 入力件数
out_Cnt = 0      ' 出力件数(空レコードを除く)
nul_Cnt = 0      ' 削除件数(Trimした結果、空レコードだった件数)

Do While Not objIText.AtEndOfStream
  ' 入力ファイル読込
  strReadLine = objIText.ReadLine
  ' 入力件数カウントアップ
  in_Cnt = in_Cnt + 1

  ' Trim関数で読込レコード内の前後スペース(半角、全角)を削除する
  strWriteLine = Trim(strReadLine)

  ' Debug用内容表示(デバッグ時は以下2行のコメント解除)
  ' WScript.Echo strWriteLine
  ' MsgBox("一時停止")

  If strWriteLine = "" Then
    ' 空レコード件数カウントアップ
    nul_Cnt = nul_Cnt + 1

  else
    ' レコード書き込み
    objOText.writeline(strWriteLine)

    ' 出力件数カウントアップ
    out_Cnt = out_Cnt + 1

  End If

Loop

' -------------------------------------------------------------
' 終了処理
' -------------------------------------------------------------
' 終了メッセージ(不要であればコメントアウト)
WScript.Echo "  INPUT : " & in_Cnt
WScript.Echo "  OUTPUT: " & out_Cnt
WScript.Echo "  NULREC: " & nul_Cnt
WScript.Echo "END"

' オブジェクトクリア&クローズ
objIText.Close
objOText.Close

Set objArgs = Nothing
Set objIText = Nothing
Set objOText = Nothing
Set objFS = Nothing


②フォルダ構成

以下の構成でフォルダを用意します。



③スクリプトファイルの配置
作成した「バッチスクリプトファイル」と「VBSファイル」をフォルダに配置します。



④処理ファイル格納場所、処理結果ファイル出力場所作成
入力ファイル格納場所、処理結果ファイル出力場所として、先程作成した「SpaceTrim」フォルダ配下に「input」フォルダ、「output」フォルダを作成します。



⑤処理対象ファイルの配置
行頭行末からスペースを削除したいファイルを 「C:\RfromL_com\SpaceTrim\input」フォルダに配置します。



⑥処理の実行
コマンドプロンプトを起動し、バッチスクリプトを格納したディレクトリに移動し、以下のコマンドを実行します。
[実行コマンド]

SpaceTrim.bat C:\RfromL_com\SpaceTrim\input\TRIM_IN.csv C:\RfromL_com\SpaceTrim\output\TRIM_OUT.csv



⑦処理結果ファイルの確認
処理が完了するとプロンプト画面が閉じられます。
出力フォルダに出力されたファイルを開くと、各行の行頭行末スペースが削除されていることがわかります。
また、当スクリプトでは行頭行末スペースを削除した結果、空行(改行コードのみのレコード)も削除するようになっています。

4.2.解説

第一引数に指定した入力ファイルID(フルパス)をVBSに渡して、VBS内でファイルから1レコードずつTRIM関数を使用し行頭行末のスペースを削除します。
スペース削除(TRIM)後のデータを第二引数に指定した出力ファイルID(フルパス)に出力しています。
また、TRIM結果の値を格納した変数に対して、IF文で空行かどうかを判定して空行でない場合に出力、空行の場合は出力対象外とすることで空行を削除しています。


5.バッチスクリプト(リテラル指定)で削除

5.1.手順

①バッチスクリプト・VBSの製造
以下のバッチスクリプトを用意します。

[SpaceTrim_Literal.bat]

@echo off
@rem ------------------------------------------------------------
@rem - 行頭・行末スペース削除(リテラル実行版)
@rem -
@rem - 引数 なし
@rem -
@rem ------------------------------------------------------------
@rem - 初期処理
@rem ------------------------------------------------------------
:STEP000
@rem カレントディレクトリ設定
set  CMD_PATH=%~dp0

@rem ------------------------------------------------------------
@rem - ファイル設定
@rem ------------------------------------------------------------
:STEP010
@rem ファイルディレクトリ設定
set  IFILEDIR=%CMD_PATH%\input
set  OFILEDIR=%CMD_PATH%\output

@rem ファイルID設定
set  IFILE01=TRIM_IN.csv
set  OFILE01=TRIM_OUT_Literal.csv

@rem ------------------------------------------------------------
@rem - TRIM処理:ファイル内の行頭・行末スペース(半角・全角)を削除
@rem ------------------------------------------------------------
:STEP020
@rem SpaceTrim実行
cscript //nologo %CMD_PATH%\SpaceTrim.vbs %IFILEDIR%\%IFILE01% %OFILEDIR%\%OFILE01%

@rem ------------------------------------------------------------
@rem - 終了処理
@rem ------------------------------------------------------------
:END

pause

exit 0

[SpaceTrim.vbs]
内容は「4.バッチスクリプト(引数指定)で削除」と同じものを使用するので割愛します。



②フォルダ構成
(フォルダ構成自体は引数指定版と同じです。)



③スクリプトファイルの配置
バッチスクリプトフォルダに配置します。
「4.バッチスクリプト(引数指定)で削除」と同じ場所に配置します。



④処理対象ファイルを配置
行頭行末からスペースを削除したいファイルを「C:\RfromL_com\SpaceTrim\input」フォルダに配置します。



⑤処理の実行
バッチスクリプト「SpaceTrim_Literal.bat」をダブルクリックして実行します。
「exit」コマンドの前に「pause」コマンドが記載されているので、処理終了前に入力待ちの一時停止が行われます。
一時停止が必要なければ「pause」の部分を消してください。



⑥処理結果の確認
出力先フォルダ「C:\RfromL_com\SpaceTrim\output」にファイルID「TRIM_OUT_Literal.csv」で空行を削除したファイルが出力されます。

5.2.解説

処理の内容としては「4.バッチスクリプト(引数指定)で削除」と同じものです。
違うのはファイルID、入出力ディレクトリを引数ではなくバッチスクリプト内に記述している点と入力・出力ファイルが固定なので、引数チェックをしていないことですね。
こちらはバッチスクリプトをダブルクリックして実行するだけで使用できるようにしたものとなっています。


6.おわりに

バッチスクリプトとかサクラエディタでのファイル整形手順の説明を「SE向け」とか「PG(プログラマー)向け」というのもおこがましいので今回から「“IT作業員向け”Tipsシリーズ」と銘打ってみました。

6.1.今回の処理対象ファイルについて

今回の処理対象ファイル「ファイル内の行頭行末に不要なスペースがある」というパターンについてです。
業務システム上で発生することはまずないんじゃないかなぁとは思います。
あったかもしれないけど思い出せないってことは滅多に無いんじゃないかと思います。

僕個人の意見としては、受信ファイルの行頭に要らないスペースがあるとか意味不明です。
DB上の項目内でも先頭にスペースがあったら意味があって存在してるスペースの可能性高いだろうし。

6.2.サクラエディタ手順の使用用途

過去の経験で不要なスペースを削除する機会があったとすると、テストデータ作成のためテスト用に手作業でファイル整形する。または検証時のエビデンス生成とか、リスト作成の為にデータを整形する時だったかなぁという記憶です。

具体例をひとつ挙げると、DBの文字列項目をそのままコピペしてデータを取得する際に使用します。
文字列のデータ項目に対して、定義されている最大文字数に満たないデータが入っていればスペース(全角または半角)で右側が埋めれらているのが一般的かと思います。そういった場合に一旦サクラエディタに張り付けてRTRIMでデータ項目の末尾スペースを消すなどすることはありました。
SQLserverもoracleもRTRIM、LTRIM、TRIM関数があるので、selectする際に対象項目に対してTRIMしちゃえばいいだけなんですけどね。

他に具体的な使用場面がぱっと浮かばなかったのですが、実際には日常的に何度も使っているのでエディタでの手順(TRIM手順も正規表現手順も)は覚えておいて損はないと思います。

日常的に何度も使っているのに使用場面がぱっとでないのは、ほぼ無意識で手が勝手に動いてるので自分がいつ使ってるか印象に残ってないからなので、僕の場合はそれぐらい使用頻度が高い操作ですね。

6.3.バッチスクリプト手順の使用用途

バッチは正直使いどころあるかな~?って感じですが、一応作ってみました。

引数チェックは適当なので未入力しかチェックしていませんが、実際に使うとなるとは最低限以下のようなチェック処理の追加が必要になります。

①入力ファイルに指定したファイルが存在するか。
②出力ファイル(フルパス)に指定したフォルダが存在するか。
(出力ファイル自体は上書きする処理になっているのでファイルの存在、非存在チェックは不要)

今の作りだと引数を2つ指定でいずれもフルパス指定となっているので、フォルダの存在チェックをしようと思うとフォルダ部分とファイルID部分に分ける必要があるかな?とかあります。

例えば以下のように引数を4つにして、入力フォルダ、入力ファイルID、出力フォルダ、出力ファイルIDと分けてしまえば各チェックをしやすくなる。とか色々あるのですが、今回のタイトル「ファイル内の行頭行末のスペースを削除する方法」とは別の話になってくるので横に置いておくことにして、この投稿では未入力チェックのみとしています。
 第一引数:入力フォルダ
 第二引数:入力ファイルID
 第三引数:出力フォルダ
 第四引数:出力ファイルID

だいたいの場合は、参画した現場で既にあるPGMの入力チェックとかに合わせるので、どういうチェック処理をどのように、どれぐらい入れるかは現場次第です。


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