• ベストアンサー

ファイル分割2

前回ファイル分割について質問させていただいた者です。 ファイル名 あいうえお.txt 内容 <A>AAA <B>BBB <C>CCC <D>DDD <E>EEE <F>FFF というファイルを ファイル名 あいうえお1.csv A,B AAA,BBB ファイル名 あいうえお2.csv C,D CCC,DDD ファイル名 あいうえお3.csv E,F EEE,FFF という感じで変換させたいと思っております。 A,B,C,D,E,F AAA,BBB,CCC,DDD,EEE,FFF に変換するプログラムは my $mae = my $filename = shift @ARGV; my $ato = "$filename.csv"; open(IN,"$mae") || die "Can't open!"; my @datas = <IN>; close (IN); my (@ichi,@ni); foreach (@datas){ if ($_ =~ /^<(.*)>(.*)$/){ push(@ichi,$1); push(@ni,$2); } } my $ichi = join(",",@ichi); my $ni = join(",",@ni); open (IN,">$ato") || die "Can't open!"; eval 'flock(IN,2);'; seek (IN,0,0); print IN ("$ichi\n"); print IN ("$ni\n"); eval 'flock(IN,8);'; close (IN); exit; こんな感じで作成したのですが、前回教えていただいた3つファイルに分割するプログラムをどのように追加するか わかりません。 ほんとにあほみたいなことを聞いているとは思いますが、 教えていただけないでしょうか? よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

こんな感じ? my $mae = my $filename = shift @ARGV; my (@ichi,@ni); $filename =~ s/\.txt$//;#拡張子.txtを取り除く $"=','; #配列の表示区切りをカンマにする open(IN,"$mae") || die "Can't open!"; $i=1; open(OUT,">$filename$i\.csv"); while(<IN>){ if(/^\n$/){ #改行で区切られている print OUT "@ichi\n@ni\n"; close(OUT); (@ichi,@ni)=((),()); $i++; open(OUT,">$filename$i.csv"); } else { if (/^<(.*)>(.*)$/){ push(@ichi,$1); push(@ni,$2); } } } close(OUT); unlink("$filename$i.csv");#作りすぎのファイルを消す close(IN);

hanabi100
質問者

お礼

ありがとうございます。 pl2batコマンドでバッチファイルにし動作させることができました。

その他の回答 (1)

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.2

No.1さんとは別の手法でサンプルを作ってみました。どのように処理しているのか表示できるようにしてありますので、よかったら試してみて下さい。 # 処理内容表示用 my $verbose = 1;   # 1:表示、0:非表示 sub lf2n {   (my $tmp = $_[0]) =~ s/\n/\\n/g;   return qq("$tmp"); } # 空行までを1ブロックとして処理するための設定 $/ = "\n\n"; # ファイル名と拡張子を分けて取得(ファイル名は出力にも使う) my ($filename, $extension) = split /\./, $ARGV[0], 2; open IN, "$filename.$extension" or die $!; # ブロック単位で読み込む while (<IN>) {   if ($verbose) {     print "block $.\n";     print " read ", lf2n($_), "\n";  # 読み込んだデータ   }   # 出力データ格納用   my @csv;   # ブロック内の各行から、ラベルとデータを取得   while (/\G<(.*)>(.*)\n/g) {     $csv[0] .= "$1,";   # ラベル行     $csv[1] .= "$2,";   # データ行     if ($verbose) {       print " match ", lf2n($&), "\n";  # マッチした部分       print "  csv[0]=", lf2n($csv[0]), "\n";       print "  csv[1]=", lf2n($csv[1]), "\n";     }   }   # ラベルとデータの行末の , を改行に置換   s/,$/\n/ for @csv;   # ファイルに出力   open OUT, "> $filename$..csv" or die $!;   print OUT @csv;   close OUT;   if ($verbose) {     print " output to '$filename$..csv'\n";  # 出力したファイル名     print "  csv[0]=", lf2n($csv[0]), "\n";     print "  csv[1]=", lf2n($csv[1]), "\n";   } } close IN; ※$. には、今読んでいるファイルから読み込んだ行数(ここではブロック数)が自動でセットされます。 ※全角空白でインデントしているので、コピーした場合はタブなどに置換して下さい。

hanabi100
質問者

お礼

ありがとうございます。 全角をとって動作させたところ 意図した動作になりました。