• ベストアンサー

for文の応用

今、S001.csvからS099.csvまでのファイルがあります。 これを下記のプログラムを書いて、新たにSA001.csvからSA099.csvまでのファイルを作りたいと考えています。 しかし、途中途中で数字が抜けているため、全てのファイルが処理できず 困っています。たとえば、S001.csvからS009.csvまでは 存在するが、S010.csvはなく、またS011.csvからは 存在するという具合です。 初歩的な質問で大変恐縮ですが、ご教示いただければ幸いです。 for ($i = 1; $i <= 99; ++$i) {  $file = sprintf("S%03d.csv", $i);  $newfile = sprintf("SA%03d.csv", $i); open (FILE, $file) or die; open (NEWFILE, ">$newfile") or die;  while (my $line = <FILE>) {  my ($aaa, $bbb, $ccc) = split(/,/, $line);  print NEWFILE join(',', $aaa, $bbb), "\n";  } close(FILE); close(NEWFILE); }

  • Perl
  • 回答数2
  • ありがとう数1

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

たとえば S010.csv がなかったときに SA010.csv を作らないでいいのなら #open (FILE, $file) or die; ←この行を open(FILE, $file) or next; ← こうする open (NEWFILE, ">$newfile") or die;  while (my $line = <FILE>) {  my ($aaa, $bbb, $ccc) = split(/,/, $line);  print NEWFILE join(',', $aaa, $bbb), "\n";  } とすればいいんじゃないですかね。 警告メッセージを出すなりはしてもいいと思いますが。

hunter_paul
質問者

お礼

初歩的なことに気付かず、すいませんでした。 無事、自分の思い通りのことがすることができました。 警告メッセージに関するアドバイスまでいただき、 ありがとうございます。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

open (FILE, $file) or die; で die してるからねぇ.

関連するQ&A

  • 一つのテキストファイルと複数のファイルの結合

    よろしくお願いします.ディレクトリ内の一つのテキストファイル(joint.txt)と複数のファイルの結合を行ごとに隣へ結合するプログラムを作成しています.ここで以下のプログラムを作成したのですが,うまくいかないため,誤っている部分をご指摘願えないでしょうか. my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); open(FILE, $dir) or die "$dir: $!"; open(FILE2,"joint.txt"); my @file = <FILE>; my @file2 = <FILE2>; close(FILE); close(FILE2); foreach my $line (@file) { foreach my $line2 (@file2) { chomp $line2; $line = "$line2.",".$line"; } } open(NEWFILE, "> $dir") or die "$dir: $!"; print NEWFILE @file; print NEWFILE @file2; close(NEWFILE); } closedir(DIR);

    • ベストアンサー
    • Perl
  • 指定の行数目から行を抽出する

    いつもお世話になっております. 環境はWindows XP Pro でActiveperlを使っています. Perlでしたいことは,「指定の行数目から行を抽出する」ことです. 具体的には以下のようにしたいと思っております. data.txt A B C D E F line.txt 2 4 6 output.txt B D F 先ほどある方からサンプルソースを教えてもらったのでそれをベースに作ってみましたが,出力のoutput.txtが空のままです. use strict; use warnings; use feature ':5.10'; use IO::File; open my $file2, '<', 'line.txt' or die "can't open input $!"; chomp(my @subjects = <$file2>); close $file2; open my $newfile, '>>', 'data_out.txt' or die "can't open output $!"; open my $file, '<', 'data.txt' or die "can't open input $!"; while (my $line = <$file>) { chomp $line; foreach my $line (@line) { print $line; if ($. eq $subjects){ say {$newfile} $line; } } } close $file; close $newfile; どこが間違っているのでしょうか.ご指摘ください.よろしくお願いします.

    • ベストアンサー
    • Perl
  • プログラムの高速化

    いつもお世話になっております.以下のプログラムをできるだけ高速化したいと思います. use warnings; use strict; my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); open(FILE, $dir) or die "$dir: $!"; while (my $line = <FILE>) { my ($a,$b,$c,$d,$e,$f) = split( /,/ , $line ); my $name = $a.",".$b; open(NEWFILE, ">> ./out/$name.txt") or die "$dir: $!"; print NEWFILE $line; close(NEWFILE); } } close(FILE); closedir(DIR); やっていることは,ディレクトリ内のテキストファイルを読み込んでいって,splitでカンマ区切りにした,$a,$bをファイル名として下のディレクトリのoutに保存していくというものです. ファイル数が数千あり,各ファイルも数千行となるため,このソースを高速化する方法はありますでしょうか.ご回答よろしくお願いします.

    • ベストアンサー
    • Perl
  • 下のディレクトリ(3つ)に含まれる同じファイル名のテキストを結合し,カレントディレクトリに出力する

    いつもお世話になっております.環境はWindows XPのActiveperlです. やりたいことは「下のディレクトリ(3つ)に含まれる同じファイル名のテキストを結合し,カレントディレクトリに出力する」ことです.具体的にはいかのようにしたいと思っています. 現在のディレクトリ/a/1.txt a b c 現在のディレクトリ/b/1.txt d e f 現在のディレクトリ/c/1.txt g h i 現在のディレクトリ/1.txt a b c d e f g h i ここで私は以下のプログラムを作成しました. use strict; use warnings; my $dirname1 = './a/'; my $dirname2 = './b/'; my $dirname3 = './c/'; opendir(DIR1, $dirname1) or die "$dirname1: $!"; while (my $dir1 = readdir(DIR1)) { next unless (-f $dir1); next unless ($dir1 =~ /\.txt$/); opendir(DIR2, $dirname2) or die "$dirname2: $!"; while (my $dir2 = readdir(DIR2)) { next unless (-f $dir2); next unless ($dir2 =~ /\.txt$/); opendir(DIR3, $dirname3) or die "$dirname3: $!"; while (my $dir3 = readdir(DIR3)) { next unless (-f $dir3); next unless ($dir3 =~ /\.txt$/); if (($dir1 == $dir2) && ($dir2 == $dir3)){ open(FILE1, $dir1) or die "$dir1: $!"; my $line1 = <FILE1>; close(FILE1); open(FILE2, $dir2) or die "$dir2: $!"; my $line2 = <FILE2>; close(FILE2); open(FILE3, $dir3) or die "$dir3: $!"; my $line3 = <FILE3>; close(FILE3); my $joint_line = $line1.$line2.$line3; open(NEWFILE, "> $dir1") or die "$dir1: $!"; print NEWFILE $joint_line; close(NEWFILE); } } } } closedir(DIR1); closedir(DIR2); closedir(DIR3); ですが,以下のようなエラーが発生しています. closedir() attempted on invalid dirhandle DIR2 at joint.pl line 51. closedir() attempted on invalid dirhandle DIR3 at joint.pl line 52. ディレクトリハンドルが使われているけれど閉じているか実際にはディレクトリハンドルでは無い時にこれらの警告が発行されるとこの警告がでるようですが,どのようにしたら解決できるのでしょうか.よろしくお願いします.

  • 12文字以上の単語リスト作成

    こんばんは。Perl初心者(プログラミングの初心者です)。 たびたびお世話になっております。 現在、カレントディレクトリにあるテキストファイルから12文字以上の単語を抽出し、新規テキストファイルにはき出すスクリプトを書こうとしているのですが、うまくいきません。 以下のようなリストを記述して見たのですが、どうやら12文字以上の単語が含む「行」を抽出しているようなのです(その処理自体も不安なのですが…)。 どこがいけないのか、そもそも根本的に間違っているのか、ご指摘いただけると非常に助かります。 ご助言よろしくお願いします。 use strict; use warnings; while ( my $file = glob '*.txt' ) { open my $reading, '<', $file or die; my @content = <$reading>; close $reading; my @results = grep(/[a-zA-Z']{12,}/,@content); foreach my $result (@results) { open (NEWFILE, ">LongWords_12.txt") or die "$!"; print NEWFILE @results; close(NEWFILE); } }

    • ベストアンサー
    • Perl
  • ディレクトリ内のテキストファイルに対する同一処理

    よろしくお願いします。現在Linuxの環境でテキスト処理をしております。 ディレクトリ内にファイル名の異なった以下のような大量ファイルがあります。 a.txt 0,1,2,3,4,5,6,7 1,2,3,4,5,6,7,8 b.txt 2,3,4,5,6,7,8,9 3,4,5,6,7,8,9,10 これらのファイルをカンマでsplitし、左から2番目の数にだけ1を引き,下のディレクトリであるoutに出力させます。出力は以下のようになります。 ./out/a.txt 0,0,2,3,4,5,6,7 1,2,3,4,5,6,7,8 ./out/b.txt 2,2,4,5,6,7,8,9 3,4,5,6,7,8,9,10 そこで以下のようなPerlのプログラムを作成しました。 use strict; use warnings; my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); print $dir, "\n"; open(FILE, $dir) or die "$dir: $!"; my @file = <FILE>; foreach $line (@file) { my ($a,$b,$c,$d,$e,$f,$g,$h) = split(/,/, $line);      my $b = $b - 1; close(FILE); } open(NEWFILE, "> ./out/$dir") or die "$dir: $!"; print NEWFILE @file; close(NEWFILE); } closedir(DIR); ですが、出力は完了するのですが、元のファイルから計算がされていません。どこがどう間違えているのかご指摘よろしくお願い申し上げます。

    • ベストアンサー
    • Perl
  • 複数行に渡る文字列の置換

    こんにちは、Perl初心者です(プログラミング全般の初心者です)。 カレントフォルダ内のテキストファイルに対して、文字列置換をするスクリプトを書こうとしています。具体的には、以下のようにストリングIDの直下に改行のみの場合(ストリングがない)は、[BLANK]という文字列を挿入したいと思っています。 TEXT_STRING_ID_001<改行> <改行> <改行> TEXT_STRING_ID_002<改行> 入門書やこのサイトの皆さまのお力を借りて、なんとか以下のようなリストを書きエラーなく置換処理ができるところまでは確認できました。 しかし、この方法だと結局1行ずつ処理していることになるので、「s/\n{3}/\n[en]\n/gm」のような置換ができません(mオプションをつけてもダメなようです)。 この問題を解決する良い方法はないものでしょうか。 (もしかすると、処理の仕方を根本から変えないといけないのでしょうか) 以下、現状のリスト: use strict; use warnings; my $dirname = '.'; opendir(DIR, $dirname) or die "$dirname: $!"; while (my $dir = readdir(DIR)) { next unless (-f $dir); next unless ($dir =~ /\.txt$/); print $dir, "\n"; open(FILE, $dir) or die "$dir: $!"; my @file = <FILE>; close(FILE); foreach my $line (@file) { $line =~ s/\n{3}/\n[BLANK]\n/gm; } open(NEWFILE, "> $dir") or die "$dir: $!"; print NEWFILE @file; close(NEWFILE); } closedir(DIR);

    • ベストアンサー
    • Perl
  • 文字コードの変換(Shift-JISからUTF8)

    文字コードがShift-JISのCSVファイルを読み込み、UTF-8のテキストファイルに出力するのに プログラムの中で変更しようとしているのですが、うまくいきません。出力ファイルの文字コードを 確認するとShift-JISのままです。 どなたか教えていただけないでしょうか? ActivePerl v5.16.0を使用し、Encodeモジュールのfrom_toを使用しています。 #!/usr/bin/perl use strict; use warnings; use utf8; use Encode; my $input_file="input.csv"; my $output_file="output.txt"; open (IN, $input_file) or die "$!"; open (OUT, ">$output_file") or die "$!"; while (<IN>){ chomp ($_); my @data=split(/,/,$_); for(my $i=0;$i<@data;$i++){ $data[$i]=Encode::from_to($data[$i],'shiftjis','utf8'); #Shift-JISからUTF-8に変換 $data[$i]=~s/\s+//g; print OUT $_; } print OUT "\n"; } close (IN); close (OUT);

    • ベストアンサー
    • Perl
  • perlについての質問です

    &あああ("ファイル名1", "AGT"); &あああ("ファイル名2", "ACA"); &あああ("ファイル名3", "TAT"); &あああ("ファイル名4", "TGA"); sub あああ{ open(FILE, "処理させるファイル") or die "$!"; my ($file, $tag) = @_; open(NEWFILE, "> $file") or die "$!"; my $x = 0; my @ti; while(<FILE>){ if($_ =~ "^>"){ $x ++; $ti[$x] = $_; } elsif($_ =~ "^$tag"){ print NEWFILE $ti[$x].$_; } } print "$x\n"; close NEWFILE; } このプログラムをサブルーチンではなく forかなんかで実行させ 自由にファイル数と$tagを設定し 実行できるようにしたいのですが できますでしょうか>< forをまわす回数を指定しSTDINなんかで指定し そのforの中でファイル処理に必要な条件や 吐き出すファイルの名前をSTDINで指定するようなものを書きたいです ちなみにperl初心者です 質問が意味不明かもしれないです>< よろしくおねがいします

    • ベストアンサー
    • Perl
  • 文字列を指定して,別のファイルでその文字列が存在する行を出力する

    いつもお世話になっております. 環境はWindows XP Pro でActiveperlを用いてプログラムをしております. この度,皆様にご意見をうかがいたいのは,「文字列を指定して,別のファイルでその文字列が存在する行を出力する」という内容です. まず,以下のテキストファイルがあります. data.txt ---------------------- A BA C DA E FA G sansyo.txt ----------------------------- B D F ------------------------------- 処理として,data.txtでsansyo.txtの行が "含まれる"行数を出力する ------------------------------- output.txt ------------------------------- 2 4 6 ここで自分なりにプログラムを組んでみました. ----------------------------------- open(FILE, "sansyo.txt"); open(FILE2,"data.txt"); @file = <FILE>; close(FILE); @file2 = <FILE2>; close(FILE2); foreach $line (@file) { foreach $line2 (@file2) { if ($line =~ $line2){ $hit = $.; } open(NEWFILE, " >> output.txt") or die "$!"; print NEWFILE $hit; close(NEWFILE); } } #ここまで ------------------------------------- ですが,永久ループに入ってしまったようにファイルはできるのですが, 出力されてきません. 間違っている点をご指摘ください.

    • ベストアンサー
    • Perl

専門家に質問してみよう