Perlのスクリプトを募集します。主観になりますが、ズバリ度によって100〜200ptを先着の方へお送りします。

 
以下のようなデータを整理するスクリプトが欲しいのです。
 
1セル目:年月日
2セル目:時間
3セル目:商品名
4セル目:属性値A
5セル名:属性値B
6セル名:属性値C
 
1〜3セル目が同じなのに、4〜6目が異なる行をマージしたいです。4〜6セル目を、「それぞれ」合体させたいのです。セルごとの合体です。
 
例:
2015-01-05,22:31:45,ラップ大,,,破れ
2015-01-05,22:31:45,ラップ大,ラインA,,
2015-01-05,22:31:45,ラップ大,ラインA,13班,
これを…
2015-01-05,22:31:45,ラップ大,ラインA,13班,破れ

年月日と日時が一致しない行は、集約の対象外です。元データは、年月日と日時でソート済みです。合体は、単純な文字列の結合でOKです。結合順は問いません。
 
不足仕様があればご指摘ください。Rubyでも構いません。よろしくお願いいたします!
 

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2016/03/25 14:05:39
  • 終了:2016/03/26 06:57:51

ベストアンサー

id:cubick No.1

cubick回答回数121ベストアンサー獲得回数352016/03/25 17:28:38

かなり雑で細かな重複チェックはしていませんが、、

$old[0] = "2015-01-05,22:31:45,ラップ大,,,破れ";
$old[1] = "2015-01-05,22:31:45,ラップ大,ラインA,,";
$old[2] = "2015-01-05,22:31:45,ラップ大,ラインA,13班,";
# @old に対してファイルからの読取等で対象のデータを入力しておく

foreach (@old) {
    @col = split(/,/);
    $key = join("|",(@col[0,1,2]) );
    
    $new{$key}[0] = $col[3] if ($new{$key}[0] eq "");;
    $new{$key}[1] = $col[4] if ($new{$key}[1] eq "");;
    $new{$key}[2] = $col[5] if ($new{$key}[2] eq "");;
}

foreach $k (keys %new) {
    $c = $k;
    $c =~ s/\|/,/g;

    print  "$c,";
    printf "%s," , $new{$k}[0];
    printf "%s," , $new{$k}[1];
    printf "%s\n", $new{$k}[2];
}
id:Mugicha2004

早速のご回答、ありがとうございます。現在、移動中です。Linux環境にて、検証してみたいと思います。とてもうれしいので、挙動結果はさておき、100ptをお送りいたします。せっかくですので、もう1回答お待ちしたいと思います…

2016/03/25 20:57:35
id:Mugicha2004

ポイント、お送りしました!

2016/03/26 06:59:34

その他の回答(1件)

id:cubick No.1

cubick回答回数121ベストアンサー獲得回数352016/03/25 17:28:38ここでベストアンサー

かなり雑で細かな重複チェックはしていませんが、、

$old[0] = "2015-01-05,22:31:45,ラップ大,,,破れ";
$old[1] = "2015-01-05,22:31:45,ラップ大,ラインA,,";
$old[2] = "2015-01-05,22:31:45,ラップ大,ラインA,13班,";
# @old に対してファイルからの読取等で対象のデータを入力しておく

foreach (@old) {
    @col = split(/,/);
    $key = join("|",(@col[0,1,2]) );
    
    $new{$key}[0] = $col[3] if ($new{$key}[0] eq "");;
    $new{$key}[1] = $col[4] if ($new{$key}[1] eq "");;
    $new{$key}[2] = $col[5] if ($new{$key}[2] eq "");;
}

foreach $k (keys %new) {
    $c = $k;
    $c =~ s/\|/,/g;

    print  "$c,";
    printf "%s," , $new{$k}[0];
    printf "%s," , $new{$k}[1];
    printf "%s\n", $new{$k}[2];
}
id:Mugicha2004

早速のご回答、ありがとうございます。現在、移動中です。Linux環境にて、検証してみたいと思います。とてもうれしいので、挙動結果はさておき、100ptをお送りいたします。せっかくですので、もう1回答お待ちしたいと思います…

2016/03/25 20:57:35
id:Mugicha2004

ポイント、お送りしました!

2016/03/26 06:59:34
id:siachan No.2

siachan回答回数78ベストアンサー獲得回数132016/03/26 03:03:08

作ってみました。属性値が4種類以上出てくるとその分だけカラムが増えてしまいますが。

use strict;
use warnings;

my @data = <DATA>;
my %hash = ();

for my $line(@data) {
	chomp $line;
	my($label,$attrs) = $line =~ /^(.*?,.*?,.*?),(.*?,.*?,.*)$/;
	for my $attr(split /,/,$attrs) {
		next unless $attr;
		$hash{$label}{$attr} = 1;
	}
}

my @out = ();
for my $label(sort keys %hash) {
	push @out,"$label,".join(',',sort keys %{$hash{$label}});
}

print "$_\n" for @out;

__DATA__
2015-01-05,22:31:45,ラップ大,,,破れ
2015-01-05,22:31:45,ラップ大,ラインA,,
2015-01-05,22:31:45,ラップ大,ラインA,13班,
id:Mugicha2004

ありがとうございました! 助かります。Perlは15年くらい前に触ったきりです。お二人のスクリプトをベースにしたいと思います。100pt、お送りしますね。

2016/03/26 06:57:42
id:Mugicha2004

ポイント、お送りしました!

2016/03/26 06:59:39

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません