LoginSignup
3
3

More than 5 years have passed since last update.

Perlで1レコード複数行のデータを処理するためのメモ

Last updated at Posted at 2017-01-08

Perlを業務で扱って1年程なので、拙い記事になりますが、お手柔らかに。。。

経緯


現場でiniファイル型(1レコード複数行)ファイルを扱ったときに、kshコマンドで1レコード1行に変換するのが面倒だったので、Perlで処理したときのメモ。
ただし、誰も保守できないとのことで没になったが、今度自分が使う際のメモ程度に記載しておく。

使用した項目


  • Perlの入力行セパレータ

Perlでは、行を定義する際のセパレータとして、デフォルトの変数"$/"に改行文字が設定されている。1レコード複数行のデータを扱う際は、この変数を操作することで複数行を1レコードとして扱うことができる。

  • パターンマッチの複数行モード

パターンマッチ演算子の"m"を使うことにより、パターンマッチで複数行モードで行うことできる。

実際のサンプル


  • テキストサンプル

以下のようなiniファイル形式のテキストファイルを扱った。

sample.txt
#
# ID=HOGE1
#

ID=HOGE1
FILE=/HOGE/TO/PATH1.txt
GRP=FUGA1
END

#
# ID=HOGE2
#

ID=HOGE2
FILE=/HOGE/TO/PATH2.txt
GRP=FUGA2
END

#
# ID=HOGE
#

ID=HOGE3
FILE=/HOGE/TO/PATH3.txt
GRP=FUGA3
END

  • Perlコード
sample.pl
#! /usr/bin/perl
use strict;
use warnings;

# 引数を変数に格納
my $argument = $ARGV[0];

# 既存セパレータの退避(オプション)と新規セパレータの設定
my $oldsep = $/;
$/ = "END";

# ファイルを開き、複数行モードで処理
open my $fh,"<",$argument;
while(<$fh>){

    # 空行だけの行をスキップする   
    next if /^\n$/;

    # 改行を[,]に変換する
    $_ =~ s/\n/,/mg;

    # [,END]を削除する
    $_ =~ s/\,END//mg;

    # ヘッダー部分の削除
    $_ =~ s/^\,{0,2}\#.+\,{2}//mg;

    # ハッシュへ一括変換
    my %foo = split(/[=,]/,$_);

    while(my($key,$val) = each %foo){
        print "[key]:$key,[val]:$val\n";

    }
}
# ファイルを閉じる
close($fh);

# 既存セパレータに戻す
$/ = $oldsep;

結果


当たり前のようだが以下のような結果になった。
コマンド結果
$ ./untitled.pl ./test.txt
"key":FILE,"val":/HOGE/TO/PATH1.txt
"key":GRP,"val":FUGA1
"key":ID,"val":HOGE1
"key":FILE,"val":/HOGE/TO/PATH2.txt
"key":GRP,"val":FUGA2
"key":ID,"val":HOGE2
"key":GRP,"val":FUGA3
"key":ID,"val":HOGE3
"key":FILE,"val":/HOGE/TO/PATH3.txt
$

もう少し正規表現の部分をスマートにできればもう少し綺麗なコードになるかも。。。
むしろワンライナーでいけるな、これ。。。

参考サイト

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3