電子書籍の厳選無料作品が豊富!

以下のインプットファイル(csv)の行と列を入れ替えるスクリプトについて質問させてください。

ID,氏名,都道府県,開始日時,終了日時
0001,山田太郎,東京都,20180110,20180120
0001,山田太郎,東京都,20180310,20180330
0002,佐藤花子,埼玉県,20171110,20171112
0003,山本正,沖縄県,20160916,20160920
0003,山本正,沖縄県,20180421,20180422
0003,山本正,沖縄県,20170707,20170808

ID、氏名、都道府県の値が同じであれば、以下のように開始日時と終了日時の値を1行にしたいのですが、どうすればいいのかわかりません。どなたか教えていただけないでしょうか?
何卒よろしくお願いいたします。

アウトプットファイル(csv)
0001,山田太郎,東京都,20180110,20180310,20180120,20180330
0002,佐藤花子,埼玉県,20171110,20171112
0003,山本正,沖縄県,20160916,20180421,20170707,20160920,20180422,20170808

質問者からの補足コメント

  • 勘違いをして、「この質問は特に30代・男性の方にリクエストされています!」を選択してしまいました。どなたでも助けていただけると助かります。

      補足日時:2018/05/15 20:31
  • インプットファイルの1行目は見出し(ID,氏名,都道府県,開始日時,終了日時)です。
    何卒よろしくお願いします。

    No.2の回答に寄せられた補足コメントです。 補足日時:2018/05/16 09:19
  • つらい・・・

    tatsu99さん、回答ありがとうございました。とても分かりやすいスクリプトで大変勉強になりました。おかげさまでやりたいことができました。

    大変申し訳ないですが、これに関連した質問をさせてください。
    今回インプットファイルを縦から横にまとめましたが、逆にアウトプットファイルをインプットファイルにして横に整列したものを再び縦に整列させるスクリプトを教えていただけないでしょうか?

    ずっと考えていていくつか試してみたのですが、うまくいきません。
    何卒よろしくお願いいたします。

    No.3の回答に寄せられた補足コメントです。 補足日時:2018/05/17 21:22
  • 返答ありがとうございます。確認点について回答させていただきます。
    確認1について、不可思議なことをお願いしてすいません。実は仕事でいくつかのツールを使用するのですが、一つだけインプットデータの形式を横に並べた形式にしないといけない仕様になっており、アウトプットもインプットと同じ横に並んだ形式になっております。そのツールを使用後、そのアウトプットを使用し、ほかのツールを使用する予定で、その際のインプットデータの形式が縦に並んだ形式なもので、今回質問させていただきました。わかりにくくてすいません。

    確認2について、はい、大丈夫です。レコード(行)の順番が違っても問題ありません。

    確認3について、見出し行は必要ありません。

    何卒よろしくお願いいたします。

    No.4の回答に寄せられた補足コメントです。 補足日時:2018/05/18 21:07

A 回答 (5件)

>逆にアウトプットファイルをインプットファイルにして横に整列したものを再び縦に整列させるスクリプトを教えていただけないでしょうか?



以下のようになります。(sample2.plとします)
使用方法は、
perl sample2.pl アウトプットファイル
と入力すると、結果が画面に表示されます。
---------------------------------
$fname = $ARGV[0];
open FH,$fname or die "open error:$!";
while(<FH>){
chomp($_);
@elm = split(/,/,$_); #カンマで分割
$npair = int((scalar(@elm) - 3) / 2); #日付の組数を取得
$key = join(',',@elm[0..2]); #先頭の3個をカンマで連結
#日付の組数分繰り返す
for ($i = 0; $i < $npair; $i++){
#画面に出力する
print $key,",",$elm[3+2*$i],",",$elm[4+2*$i],"\n";
}
}
close FH;
-------------------------------------------
    • good
    • 0
この回答へのお礼

tatsu99さん、おかげさまで自分がやりたいことができました。ありがとうございました。また、スクリプトもわかりやすくコメントも付けていただき勉強になりました。
返事が遅くなりすいませんでした。

お礼日時:2018/06/01 01:04

>今回インプットファイルを縦から横にまとめましたが、


>逆にアウトプットファイルをインプットファイルにして横に整列したものを再び縦に整列させるスクリプトを教えていただけないでしょうか?

以下の点、確認させてください。

確認1)元のインプットファイルを使えば、アウトプットファイルからインプットファイルを作り直す必要はないと思います。
わざわざ、元に戻すスクリプトを作る理由は何故でしょうか?

確認2)スクリプトで元に戻した場合、完全に元には戻りませんが、宜しいでしょうか。例えば以下のようになります。
元のインプットファイルが以下の場合、
0001,山田太郎,東京都,20180310,20180330
0001,山田太郎,東京都,20180110,20180120
0003,山本正,沖縄県,20160916,20160920
0002,佐藤花子,埼玉県,20171110,20171112
0003,山本正,沖縄県,20180421,20180422
0003,山本正,沖縄県,20170707,20170808

スクリプトで作り直したインプットファイル
0001,山田太郎,東京都,20180110,20180120
0001,山田太郎,東京都,20180310,20180330
0002,佐藤花子,埼玉県,20171110,20171112・・・・①
0003,山本正,沖縄県,20160916,20160920・・・・②
0003,山本正,沖縄県,20180421,20180422
0003,山本正,沖縄県,20170707,20170808
①②の箇所が元のファイルと違ってきます。

確認3)
スクリプトで作り直す場合、作り直したインプットファイルには、見出し行は出力しませんがそれでよろしいでしょうか?
この回答への補足あり
    • good
    • 0

No2です。


以下のスクリプトを作成します。(sample.plとします)
1行目が見出しなので、1行目はスキップします。
以下のコマンドを実行してください。
perl sample.pl インプットファイル名
結果が画面に表示されます。

ファイルに出力する場合はリダイレクトしてください。
perl sample.pl インプットファイル名 > アウトプットファイル名
とすると、アウトプットファイルに結果が出力されます。
--------------------------------------
$fname = $ARGV[0];
open FH,$fname or die "open error:$!";
%arr = ();
while(<FH>){
if ($. == 1) { next; } #1行目はスキップする
chomp($_);
@elm = split(/,/,$_,5); #カンマで分割
$key = join(',',@elm[0..2]); #先頭の3個をカンマで連結
$day = join(',',@elm[3..4]); #後の2個をカンマで連結
if (exists($arr{$key})){
#既存なら日付を連結
$arr{$key} = $arr{$key} . ',' . $day;
}else{
#新規なら日付を記憶
$arr{$key} = $day;
}
}
close FH;
#画面に出力する
foreach $key(sort(keys %arr)){
print $key,",",$arr{$key},"\n";
}
-----------------------------------
この回答への補足あり
    • good
    • 0

インプットファイルの1行目は、


見出し(ID,氏名,都道府県,開始日時,終了日時)でしょうか?
それとも
データ(0001,山田太郎,東京都,20180110,20180120 等)でしょうか?
この回答への補足あり
    • good
    • 0

どういう順番に出力するかという問題はありそうな気がするけど, ハッシュを使うのが簡単じゃないかなぁ.

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!