技術とか戦略とか

証券レガシーシステムを8年いじってから転職した普通の文系SEによるブログ。技術のみではなく趣味の戦略考察についても。

viで開けない巨大なファイルを開く(改行コード無し固定長レコード編)

4GB以上の改行コード無し固定長レコードのファイルの中から一部のレコードを抜き出す機会があったのですが、viエディタでも開けず、Windowsに落としてもエディタ(サクラエディタ、Stirling)でも開けなかったので、以下のように対処しました。
cutコマンドを使用して開ける大きさのファイルにするのがミソです。
 
1.下記コマンドで必要なレコードの存在位置にあたりをつける
例えば、レコード長100バイトで100レコード(合計10000バイト)のファイルについて、キー項目「1234567890」の存在位置を調べたい時、以下のコマンドによりあたりをつけることができます。
 
cut -b 1-5000 hoge | grep "1234567890" | wc -l
 
まず、cutコマンドにより、1バイト目から5000バイト目を抜き出しています。
次に、抜きだした結果に対して「1234567890」という文字が存在するかどうか調べています。
存在していれば、その次のwcコマンドに標準出力が渡り、1が出力されます。
存在しなければ、標準出力は渡らないので、0が出力されます。
 
2.徐々に範囲を狭める
例えば、1-5000バイトにキー項目が存在していた場合は、次に以下のようにコマンドを発行します。
 
cut -b 1-2500 hoge | grep "1234567890" | wc -l
 
これでもし1-2500バイトの範囲にキー項目が存在しなければ、次は以下のようにコマンドを発行し、2501-5000バイト目のどこかにキー項目が存在することを確認します。
 
cut -b 2501-5000 hoge | grep "1234567890" | wc -l
 
このように、二分検索の要領で、徐々に範囲を狭めていくのがポイントです。
 
3.レコードを抜きだす
開ける大きさにまで範囲が狭まったら、「| grep "1234567890" | wc -l」の箇所をリダイレクトに変更してファイルを出力します。
 
cut -b 2501-5000 hoge > hoge_tmp
 
なお、抜きだしたファイルには改行コードが付与されているので、下記コマンドで改行コードを削除します。
 
tr -d '\n' < hoge_tmp > hoge_tmp2
 
これで、目的のレコードを含む開ける大きさのファイルを抽出できます。
 
--------------------
 
なお、今回私はやっていませんが、一部レコードを編集した後、最終的に全レコードを結合し直す必要がある場合は、以下の手順でできるはずです。
①cutコマンドで「編集対象のレコードの前のファイル」「編集対象のレコードを含むファイル」「編集対象のレコードの後ろのファイル」の3つに分割する。
②「編集対象のレコードを含むファイル」を編集する。
③「編集対象のレコードの前のファイル」「編集対象のレコードを含むファイル」「編集対象のレコードの後ろのファイル」をcatコマンドで結合する(trコマンドで改行コード削除も行う)。