ファイルから特定の範囲を除外するプログラムがうまく動かない

このQ&Aのポイント
  • ファイルから特定の範囲を除外するプログラムを書いていますが、うまく動作しません。
  • プログラムでは特定の範囲の行を削除したいです。
  • 何か間違いがあるのでしょうか?教えてください。
回答を見る
  • ベストアンサー

until文

初歩的な質問ですみません。 file1 あいうえお かきくけこ さしすせそ たちつてと   ・   ・   ・   ・ なにぬねの はひふへほ まみむめも があります。 ・・・・の部分を消したくて、以下のようなプログラムを書いたのですが、 上手くいきません。 教えてください。お願いします。 @ARGV = ("file1"); $^I = ".bak"; while(<>){ $a = 0; chomp($_); if(/たちつてと/){ $a = 1; until(/なにぬねの/){ $a = 1; } }; if(/なにぬねの/){ $a = 0; }; if($a = 1){ }else{ print "$_\n"; }; };

  • Perl
  • 回答数3
  • ありがとう数4

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

  • ベストアンサー
  • nightowl
  • ベストアンサー率44% (490/1101)
回答No.3

こんばんは。お礼ありがとうございます。 >消した部分に別のファイルから読み込んだものを >書き加えたいのですが、どこに何を付け加えたら >よいのでしょうか? 「なにぬねの」の行でフラグ(意味がわかるよう変数名は書き換えました) を元に戻すときにその処理を入れてやりましょう。 $infile = "file2"; # 読み込むファイル名を指定 $skip = 0; while (<>) { if (/なにぬねの/) { $skip = 0; # フラグをクリア open IN, $infile; # ファイルハンドル IN でオープン while ($line = <IN>) { # IN から1行ずつ $line に読み込む print $line; } close IN; # 帰りは戸締りを忘れずに print "\n"; } # End of if (/なにぬねの/) print if $skip == 0; $skip = 1 if /たちつてと/; } print "\n"; 参考書はお持ちでしょうか。オライリー・ジャパンの「初めての Perl 第3版」 (Randal L. Schwartz、Tom Phoenix 著、近藤 嘉雪訳)などどうぞ。 http://www.oreilly.co.jp/BOOK/lperl3/

参考URL:
http://www5a.biglobe.ne.jp/~n_rieko/perl/,http://www.rfs.co.jp/sitebuilder/perl/05/
aattmm
質問者

お礼

nightowlさま、ありがとうございます。 参考図書、参考URLも教えていただき、 本当にありがとうございました。 早速、本を買って勉強したいと思います!!

その他の回答 (2)

  • nightowl
  • ベストアンサー率44% (490/1101)
回答No.2

訂正です。chomp し忘れてましたね。 でも、「$_」にすでに改行が含まれていることをうまく利用して print "$_\n" if $a == 0; のところは print if $a == 0; と書けます(print は引数なしで $_ を出力するから)。 そして最後に「print "\n";」してやりましょう。 それから、if 文や while 文などブロックの外側の「;」は必要ありません。

aattmm
質問者

お礼

ありがとうございました!! 出来ました! 更に質問なのですが、 消した部分に別のファイルから読み込んだものを 書き加えたいのですが、どこに何を付け加えたら よいのでしょうか?

  • nightowl
  • ベストアンサー率44% (490/1101)
回答No.1

こんにちは。until もループの1種ですから while ループの中で使うと ぐーんと遅くなりますし、このように脱出条件を間違えると 無限ループしてしまいます。ループの中だけ単純に書きますと、 $a = 0; # フラグ変数はループの外に出して while (<>) { $a = 0 if /なにぬねの/; print "$_\n" if $a == 0; $a = 1 if /たちつてと/; } その他ここの問題点として、 if($a = 1){ }else{ print "$_\n"; }; }; ・「$a = 1」は代入式です。条件判定なら「$a == 1」としなければ。 ・if ブロックの中身が空です。条件をひっくり返すか、 unless を使ったほうがいいでしょう。 unless ($a == 1) { print "$_\n"; }

関連するQ&A

  • perlの「until」ループ文

    こんにちは。以下のループ文ですが、 --- print "初期値を入力してください:\n"; $number = <STDIN>; chomp($number); until ($number > 16) { print "数値:$number\n"; $number += $number; } --- 実行画面で「2」を入力すると、 数値:2 数値:4 数値:8 数値:16 のように出力されます。 なぜでしょうか?2,3,4....16じゃないの? どなたか、教えてください。よろしくお願いします。

    • ベストアンサー
    • Perl
  • Spliceを使った配列移動

    以前Spliceを使った配列の移動方法を教えていただきましたが、 open( FH, $file) or die "Can't open"; @list = <FH>; close(FH); push(@list,@list[$b-1]); #配列を最後列にコピー open (OUT,"> $file"); print OUT @list; close (OUT); とさせると、最後の配列を5列目に追加したいのですが4列目に追加されてしまい、困っています。 2番目の配列を新たに5列目にこうしたいのに 1コメントA コメントB 2あいうえお かきくけこ さしすせそ 3たちつてと なにぬねの はひふへほ 4らりるれろ まみむめも 5あいうえお かきくけこ さしすせそ 4列目の配列の後ろに追加されてしまう 1コメントA コメントB 2あいうえお かきくけこ さしすせそ 3たちつてと なにぬねの はひふへほ 4らりるれろ まみむめもあいうえお かきくけこ さしすせそ このようになってしまいます。 宜しければ対処法をお願いします。

    • ベストアンサー
    • Perl
  • 改行を読み飛ばす

    以下のようなファイルを読み込みたいのですが…. -------------------------------------------------- あいうえを かきくけこ さしすせそ たちつてと -------------------------------------------------- のように1行文字列があって,1行空白行(改行のみ)があって…のような繰り返しのファイルなんですが,空白行を読み飛ばして続けて -------------------------------------------------- あいうえお かきくけこ さしすせそ たちつてと -------------------------------------------------- のように表示させる場合はどのように書いたらよいですか? -------------------------------------------------- while(fgets(str,256,fpin)){   if(strcmp(str,"\n")!=0){    printf("%s\n",str);   } } -------------------------------------------------- と書いたのですが,空白行も表示されてしまいます. 何か間違えているでしょうか? それとも実はファイルの空白行は改行じゃないとかでしょうか?

  • definedの使い方が間違ってますか?

    こんばんは。 色々試してみたのですが、どうしてもうまくいかないので質問させてください。 リストの$f1とファイルの$aaがマッチして、 かつリストの$f3とファイルの$bbがマッチした場合に、 $f4を付け加えてprintしたいのですが、 ★マークの処理で、リストの$f3とファイルの$bbがマッチしていないものまで printされてしまうことがあります。 $aaとマッチするものがリストに2つ以上ある時にこの現象がおきるようなのですが、 どの辺を直したらよいのかわかりません。 definedの使い方がおかしいのでしょうか? 見よう見まねで書いたので、▲マークあたりの指定も自信がありません。 #リスト読み込み open LIST, "./list" or die; while (<LIST>) { chomp; if (/(.*) (.*) (.*) (.*)/) { $f1 = $1; $f2 = $2; $f3 = $3; $f4 = $4; } $xx{$f1} = $f4; #▲ $yy{$f1} = $f3; #▲ } close LIST; #ファイル読み込み if ($#ARGV >= 0) { @files = @ARGV; } foreach $file (@files) { open FILE, $file; while (<FILE>) { chomp; if (/^([^t]+)\t(.*)$/) { $aa = $1; $bb = $2; if (defined($xx{$aa})) { if (defined($yy{$bb})) { # ★ print "$aa\t$bb\t\#【$xx{$aa}】\n"; } } } } close FILE; } どうかご教示お願いいたします。

    • ベストアンサー
    • Perl
  • データからある文字列の次の行を出力するには

    perlの初心者です。はじめまして。 質問タイトルそのままなのですが、データからある文字列の次の行を出力するにはどのような記述をすればよろしいでしょうか?よろしくお願いします。 ・データは1ファイルで2000あります。1つのデータは[X,Y]で始まり、次の[X,Y]の前までになります。 ・出力はCSVファイル。 ・DAT errがあった場合はその次の行を出力。なかったら、DAT列は空白にする。 #!/bin/perl open(FILE,"<$ARGV[0]"); open(OUT,">$ARGV[0].csv"); ########################## err count ########################### print OUT "X,Y,NUMBER,DAT,\n"; while(<LOG>){ if($_ =~ /X=(.+)\,Y=(.+)/){ chomp($_); print OUT "\n$1,$2,"; } if($_ =~ /NUMBER (.+)/){ print OUT "$1,"; } if($_ =~ /DAT err/){ print OUT "PASS,0,"; } } close(OUT);

    • ベストアンサー
    • Perl
  • perlのdo-while文で抜け出せない 

    perlのwhile,do-while,last文に関する質問です。 1) code1のようなプログラムを作ったのですが   eでdo_whileを抜け出すことができませんがなぜでしょうか。 ---code1(eで抜け出せない)(NG)--- my $sum=0; do{  my $a=<STDIN>;  chomp($a);  $sum=$sum+$a; }while($a ne 'e'); print $sum; -------------------------------- 2) 抜け出す方法をいろいろ試していたら   while(1)にしてlastで抜けるようにすると   code2ではeで抜け出すことができるように   なりましたが、   do~while(1)にしたcode3では、  「Can't "last" outside a loop block at …」C   というエラーが発生します。   code2とcode3はwhileがdo~whileになって   条件を見る位置がループの始めか終わりの   違いだけなのに、なぜ、code2ではOKで、   code3ではエラーになるのでしょうか。 ---code2(eで抜け出せる)(OK)----- my $sum=0; while(1) {  my $a=<STDIN>;  chomp($a);  last if ($a eq 'e');  $sum=$sum+$a; }; print $sum; --------------------------------- ---code3(エラーになる)(NG)----- my $sum=0; do{  my $a=<STDIN>;  chomp($a);  last if ($a eq 'e');  $sum=$sum+$a; }while(1); print $sum; --------------------------------- よろしくお願いします。 Windows7 , ActivePerl(v5.16.3)

    • ベストアンサー
    • Perl
  • 歌詞ファイルを作りたくて・・・

    あいうえお かきくけこ さしすせそ たちつてと なにぬねの はひふへほ というテキストファイルを綺麗に あいうえお  たちつてと かきくけこ  なにぬねの さしすせそ  はひふへほ という感じにソフトはないでしょうか?

  • 連想配列で時間短縮したい

    aaa.txt 06011800, 5.3 06012100, 5 06020000, 4.5 06020300, 6.2 … bbb.txt 06011800, 5.1 06012100, 7.5 06020000, 5.1 06020300, 9.3 … という二つのファイルがあります。 以下のプログラムを用いて、 06011800, 5.3, 5.1 06012100, 5, 7.5 06020000, 4.5, 5.1 06020300, 6.2, 9.3 … といった感じでデータを作る事に成功したのですが、どうしてもループに無駄が多く、時間がかかってしまいます。 連想配列などを使えば時間が短縮出来そうなのですが、よくわかりません。 ご教示いただけないでしょうか。 以下、作成したプログラム。 $csvfile1 = $ARGV[0]; $csvfile2 = $ARGV[1]; open(DAT1, $csvfile1) || die $!; while($line=<DAT1>) { chomp($line); @dat = split(/,/,$line); open(DAT2, $csvfile2) || die $!; while($line2=<DAT2>) { chomp($line2); @dat2 = split(/,/,$line2); if($dat[0] == $dat2[0]){ print "$dat[0],$dat[1],$dat2[1]\n"; } } } close(DAT);

    • ベストアンサー
    • Perl
  • データベースの抽出

    ファイル名|サイズ|種類 あいうえお|123456|単行本 かきくけこ|134679|雑誌 さしすせそ|235689|単行本 たちつてと|124578|画集 なにぬねの|164973|参考書 はひふへほ|437619|雑誌 まみむめも|194376|単行本 このようなデータがあったときに「種類」が「単行本」の行だけを別のシートに表示したい場合はどのようにすればよろしいでしょうか?

  • Perlによるディレクトリ内の連続的な大量データ処理

    Perlのテキスト処理に関する質問です.やりたいことはあるディレクトリ内に10000個ほどの(1)のようなテキストデータがあります.ここで私は(2)のプログラムを作成しました.しかしながら,このプログラムだと10000個あるテキストデータの一つしか処理できません.この処理内容をディレクトリ全体に適用させる方法はありますでしょうか?File::Find::Ruleなどがネット上にあったので使おうと努力しましたができませんでした.どなたかよろしくお願いします. (1)  2020 01 01 00 109.18970 18.36816 -2.317 -2.459 292.712 0.013 91.276 30.618 292.712 0.013 -2.317 -2.459 998.793 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 2020 01 01 00 109.54297 18.39178 -2.702 -2.652 292.653 0.013 90.044 30.676  292.653 0.013 -2.702 -2.652 993.902 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 ・ ・ ・ ・ (2) use warnings; open INFILE, '<', '2020-01-01_00.txt' or die "file open error: $!"; while( <INFILE> ){ chomp if( /\n$/ ); $Year = substr($_,0,4); chomp if( /\n$/ ); $Month = substr($_,5,2); chomp if( /\n$/ ); $Day = substr($_,8,2); chomp if( /\n$/ ); $Time = substr($_,11,2); chomp if( /\n$/ ); $Lon = substr($_,16,9); chomp if( /\n$/ ); $Lat = substr($_,29,8); chomp if( /\n$/ ); $Temp = substr($_,57,7); chomp if( /\n$/ ); $Hum = substr($_,76,6); chomp if( /\n$/ ); $Ozone = substr($_,85,6); chomp if( /\n$/ ); $Rad = substr($_,140,5); $data = $Year. "-".$Month."-".$Day." ".$Time." ".$Lon." ".$Lat." ".$Ozone." ".$Rad." ".$Hum." ".$Temp."\n"; open($data, ">", "data.txt") or die("error :$!"); } # ファイルを閉じる close INFILE; exit;  

専門家に質問してみよう