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

前回ファイル分割について質問させていただいた者です。

ファイル名 あいうえお.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つファイルに分割するプログラムをどのように追加するか
わかりません。

ほんとにあほみたいなことを聞いているとは思いますが、
教えていただけないでしょうか?
よろしくお願いします。

A 回答 (2件)

こんな感じ?


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);
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/12/18 02:00

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;

※$. には、今読んでいるファイルから読み込んだ行数(ここではブロック数)が自動でセットされます。
※全角空白でインデントしているので、コピーした場合はタブなどに置換して下さい。
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/12/18 01:59

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