ファイルから改行のみの空レコード(空行)を削除


ファイルの途中や、ファイルの末尾に余計な改行のみの空レコードがあった場合に空レコード(以降、空行と記載)だけを削除する方法です。
そうそうあることでは無いですが。

CONTENTS

1.概要
2.テキストエディタ(ソート)で削除
 2.1.手順
 2.2.解説
3.テキストエディタ(正規表現)で削除
 3.1.手順
 3.2.解説
4.バッチスクリプト(引数指定)で削除
 4.1.手順
 4.2.解説
5.バッチスクリプト(リテラル指定)で削除
 5.1.手順
 5.2.解説
6.おわりに

1.概要

冒頭にも書いた通り、ファイルの途中やファイル末尾に不要な改行のみの空行が含まれてた場合にファイル内から空行を削除する方法です。

方法としては大まかに以下の2種類で削除します。
 ①テキストエディタで削除
 ②バッチスクリプトで削除

①のテキストエディタで削除には、ソート機能を使用する場合と、正規表現を使用する場合の2パターンを記載します。

本投稿ではサクラエディタを使用していますがソート機能、正規表現が使用できれば他のテキストエディタでもできます。

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

2.テキストエディタ(ソート)で削除

2.1.手順

①空行が含まれているファイルを(テキストエディタ)サクラエディタで開きます。


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


③「ALT」キー + 「A」キーでファイル内をソートします。


④ソートすると空行が全てファイルの先頭にくるので、空行の部分を選択して削除します。

2.2.解説

ファイル内全体を昇順ソートすることで空行がファイル先頭にまとまり削除しやすくしてから削除する方法となっています。
手順としてはショートカットだけで行えるので非常に簡単です。
ただし、レコード順に意味をもっている場合は並び順が変わってしまうので使用に適さないです。


スポンサーリンク

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

3.1.手順

①空行が含まれているファイルを(テキストエディタ)サクラエディタで開きます。
②「CTRL」キー + 「R」キーで置換ウィンドウを表示します。
③置換前の欄に「^¥r¥n」を、置換後の欄を「」(空欄)に設定します。
④正規表現(E)のチェックをオンにして「ALT」キー + 「A」キー で全て置換を実行。


これで空行が削除されます。

3.2.解説

正規表現で「^」が行頭、「¥r¥n」が改行コードを指定しているので、行頭に改行コードが設定されている箇所の改行コードのみを抽出。

置換後の欄に「」(空欄)が指定されているので置換すると、改行コードのみの空行が削除されることになります。

また、今回は空行の改行コードがCRLFなので置換前の欄を「^¥r¥n」としていますが空行の改行コードがCR、LFの場合は置換前の欄をそれぞれ以下の指定に変更してください。

CRの場合「^¥r」
LFの場合「^¥n」

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

4.1.手順

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

[BLANKLINE_DEL.bat]

@echo off
@rem ------------------------------------------------------------
@rem - 改行のみレコード削除
@rem -
@rem - 引数1 %1
@rem - 格納先パス(説明:格納先パスをフルパスで設定する。)
@rem - 例:C:¥Temp¥BLANKLINE_DEL
@rem -
@rem - 引数2 %2
@rem - ファイル名(説明:ファイル名を設定する。)
@rem - 例:INPUTFILE.csv
@rem -
@rem ------------------------------------------------------------
@rem 空行を削除して、convフォルダに出力
findstr "." %1¥%2 > %1¥CONV¥%2

@rem CONVフォルダから、格納先パスに戻す(move移動)
move /y %1¥CONV¥%2 %1¥

exit


②上記のバッチスクリプトフォルダに配置します。
ここではCドライブ配下に「Temp」フォルダ、その直下に「00_PGM」というフォルダを作成し格納していますが場所はどこでも良いです。


③空行を削除したいファイルを任意のフォルダに配置し、配置したフォルダ直下に「CONV」フォルダを作成します。
ここでは先程の「Temp」フォルダ直下に「01_INPUT」というフォルダを作成しファイルを格納しています。


④コマンドプロンプトを起動し、バッチスクリプトを格納したディレクトリに移動。
コマンド「BLANKLINE_DEL.bat C:¥Temp¥01_INPUT INPUTFILE.csv」を実行します。


⑤処理が完了するとプロンプト画面が閉じられます。
先程格納したファイルを再度開くと、空行が削除されていることがわかります。

4.2.解説

引数に渡されたファイルパス+ファイルIDのファイルに対し「findstr」(ファイルから文字列を検索する)コマンドを使用。
検索条件に「.」(ドット:改行を除いたすべての文字列を対象とする正規表現)を指定して文字列を抽出。
抽出結果を「>」コマンドで「CONV」フォルダ配下にファイル出力しています。

コマンドライン実行が前提となっているで、使用には別バッチからの呼び出しかスケジューラーによる実行になります。
タスクスケジューラーで実行する場合には、以下のように引数に渡す値を設定して登録します。



スポンサーリンク

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

5.1.手順

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

@echo off
@rem ------------------------------------------------------------
@rem - 改行のみレコード削除(リテラル実行版)
@rem - 
@rem - 引数 なし
@rem - 
@rem ------------------------------------------------------------
@rem ファイルID
set  IFILE001=INPUTFILE2.csv
set  OFILE001=OUTPUTFILE2.csv

@rem 入出力ディレクトリ
set  IFILEDIR=C:¥Temp¥01_INPUT
set  OFILEDIR=C:¥Temp¥02_OUTPUT

@rem 空行を削除して、出力ディレクトリに出力
findstr "." %IFILEDIR%¥%IFILE001% > %OFILEDIR%¥%OFILE001%

pause

exit


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


③空行を削除したいファイルを「set IFILEDIR=C:¥Temp¥01_INPUT」で指定した通りのフォルダに配置します。


④「set OFILEDIR=C:¥Temp¥02_OUTPUT」で指定した出力先のフォルダを作成します。


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


⑤出力先フォルダ「C:¥Temp¥02_OUTPUT」にファイルID「OUTPUTFILE2.csv」で空行を削除したファイルが出力されます。

5.2.解説

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

6.おわりに

今回の処理対象としたファイルのように空行が含まれるパターンはあまり無いというか、基本的には無いのが正しいですが稀に発生する時があります。

対象のファイル(空行の発生するファイル)が処理の最終出力結果で運用上、手作業でファイルを開いて使用する際にはテキストエディタでの削除方法が使えます。
それとは別に、対象のファイル(空行の発生するファイル)が、システム内の中間ファイルで後続の処理がまだある場合にはバッチスクリプトでの削除方法が使えます。

今回のような空行が含まれるファイルが発生してしまう事象として過去経験したのは、以下の条件を満たす場合でした。

①OracleDBから「PUT_LINE」プロシージャを使用してファイル出力
②出力するファイルの最終項目が日本語項目(マルチバイト項目)
③Oracleサーバーの NLS_LANG の設定とデータベース・キャラクタ・セットが一致していない

これは「[Oracle] UTL_FILE.PUT_LINE で書き出される改行コードがおかしい!」(外部サイト)で書かれている通り、出力されるファイル内で改行コードCRLFとLFが混在して出力されてしまう事象が発生します。
上記サイトには書かれていないですが、その際にファイル末尾に不要な空行が出力されてしまう事があります。

処理するシステムで空行を考慮して取り込む作りになっていれば問題ないのですがそうでない時に空行の含まれたファイルを取り込むと、レイアウト通りのレコードになっていないなどの理由でエラーになってしまいます。
また、この空行が出力されてしまうのが、必ず発生するわけではないところがまた厄介なところです。
テストでは発生していなかったために、本番で動いてしばらくたったころに急に発生したりしてファイルを取り込もうとした際に取り込みエラーが発生して発覚します。

本格対応としては、先に示した発生条件①~③のいずれかを満たさないようにすることですが状況によって対応が(できないわけではないが、影響範囲が大きいなどの理由で)難しいことがあるので、そういった場合に暫定対応的に削除したい時にバッチスクリプトでの削除方法が使用できます。
(あくまで暫定なので本格対応出来るのが一番ですが・・・)



日経ITエンジニアスクール コマンド&スクリプト最強の指南書