perlでテキストデータの指定行に書き込み

このQ&Aのポイント
  • perlを使用してテキストデータの指定行に書き込む方法について教えてください。
  • データには「データNO」「登録NO」「名前」「カテゴリー」「金額」が登録されており、フォームを使用してデータを編集し、一致した行のみを書き換えたいです。
  • 現在のプログラムでは書き換えができていないため、どのように修正すれば一行のみを書き換えることができるのか教えてください。
回答を見る
  • ベストアンサー

perlでテキストデータの指定行に書き込み

たびたびお世話になります。 データには、「データNO」「登録NO」「名前」「カテゴリー」「金額」が登録されています。 もともとあったデータをフォームで編集、送信してデータNO($d_no)と一致した行だけを書替え(上書き)したいんですが、どうしても方法がわかりません。 open(IN,"../save_data/sdeta.txt"); @data = <IN>; close(IN); foreach(@data){ chop($sdata); ($d_no,$s_no,$s_name,$d_class,$s_price) = split (/=/, $sdata); if( $value eq $d_no){ $sdata="$in{'d_no'}=$in{'s_no'}=$in{'s_name'}=$in{'d_class'}=$in{'s_price'}\n"; }else{ $sdata="$d_no=$s_no=$s_name=$d_class=$s_price\n" } } open(OUT,">../save_data/sdeta.txt") || &error("オープンエラー"); print OUT @data; close(OUT); 上のプログラムを書いても、書替えできませんでした。 どのように直せば一行のみの書替えが出来るんでしょうか。 よろしくお願い致します。

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

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

まず、お約束として、スクリプトの最初の方に use strict ; use warnings ; を書きましょう。こうすると、宣言してない変数とか、未定義値を文字や数値として利用したりするなど、通常はそのまま使えることが、エラーにや警告になります。 で、おそらく、$sdataについてエラーまたは警告が出るはずです。提示された範囲で$sdataに値が設定されているのは > $sdata="$in{'d_no'}=$in{'s_no'}=$in{'s_name'}=$in{'d_class'}=$in{'s_price'}\n"; > $sdata="$d_no=$s_no=$s_name=$d_class=$s_price\n" この2行だけです。 > ($d_no,$s_no,$s_name,$d_class,$s_price) = split (/=/, $sdata); では、最初の$sdataは無いので前の変数は全部空だし、2回目以降は先の2行のどちらかの内容が繰り返されるだけです。 初心者とのことですが、それならなおさら基礎を勉強してください。 ネットのサンプルコードを参考にするにも、どこが必要か見極められなければ意味がありません。

kari729
質問者

お礼

回答ありがとうございました。 use strict ; use warnings ; をスプリクトの最初の方につけたら、言われたとおりエラーが出ました。 今回質問した箇所を削除して転送してもエラーが出たので、 他にも色々な箇所が間違っていたようです・・・。 kmeeさんの言われたように、もう一度基礎から勉強してみようと思います。 どうもありがとうございました。

その他の回答 (2)

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

「$sdataは「$d_no,$s_no,$s_name,$d_class,$s_price」をまとめたものかな、と思っていたんですが。」というのは, どうしてそう思われたのでしょうか? 少なくとも, このスクリプト中で $sdata に値を設定する前に chop とか split とかしてますよね. foreach のデフォルトの変数はなんでしょうか?

kari729
質問者

お礼

色々とエラーが見つかったので、もう一度基礎から勉強してみます。 回答ありがとうございました。

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

そりゃそうでしょう. $sdata ってなに?

kari729
質問者

補足

この$sdataがそもそも必要ないんでしょうか? $sdataは「$d_no,$s_no,$s_name,$d_class,$s_price」をまとめたものかな、と思っていたんですが。 色々なサイトを参照しながら作成しているんですが、 perl初心者なので、全てが理解しているわけではありません。 すみません。 どのように直したら、変更していない行はそのままで、 一行だけ上書き保存が出来るんでしょうか。 少しいじると編集した1行だけ残して、あとのデータは全て消えてしまったりします。 よろしくお願い致します。

関連するQ&A

  • テキストデータから指定した1行を抜き出して表示

    perl初心者です。 説明不足の箇所もあるかと思いますが、よろしくお願いします。 テキストデータから指定した1行を抜き出して表示するのにはどうしたらいいんでしょうか。 data.txtの中に=で区切られた文字が入っているとします。 1=にんじん=150 2=じゃがいも=200 3=たまねぎ=100 左から$s_no,$s_name,$s_priceという変数になっています。 これを print <<"EOF"; <TABLE class="list_index"> EOF open(IN,"../indata/sdeta.txt"); @data = <IN>; close(IN); foreach $sdata (@data){ chop($sdata); ($s_no,$s_name,$s_price) = split (/=/, $sdata); print <<"EOF"; <TR> <TD class="list2">$s_no</TD> <TD class="list3">$s_name</TD> <TD class="list4">$s_price円</TD> <TR> EOF } print <<"EOF"; </TABLE> EOF という感じでテーブルにデータを全て一覧表示させました。 ここから、$s_noで表示されている「1」「2」「3」をクリックすると、 別ページにとんで、クリックした番号の1行を編集用のフォームに表示させたいです。 フォームに表示させる方法はわかっているんですが、 クリックで指定した1行だけを表示する方法がわからずに困っています。 よろしくお願い致します。

    • ベストアンサー
    • Perl
  • Perlでテキストファイル読み込み

    基本的な質問ですみません。 サーバ上のテキストファイルを読み込んで ローカルのテキストファイルに書き込むというだけなのですが 何度やってもできません。 以下プログラムですが #!usr/bin/perl open(IN,"http://*****/***/***.txt"); $file = <IN>; close(IN); open(OUT,"> a.txt"); print(OUT "$file"); close(OUT); サーバのアドレスは、URLうってみて見れたのでhttp://***(以下略)であってると思います。 サーバのテキストにはchmodで777と権限を与えました。 プログラムに問題あるのでしょうか。 この場合考えられる原因を教えてください。

    • ベストアンサー
    • Perl
  • dataファイルの特定の行から特定の行をダンプさせるには?

    $ cat data.txt #No1. abc... #No2. def... #No3. ghi... #No4. jkl... #No5. mno... なるデータの、例えば#No2.から#No4.までのデータだけをダンプするのに、 open(IN,"data.txt"); my $flag=0; while(<IN>){ if ( $_ =~ /#No2./ && $flag == 0) { $flag=1; } if ( $_ =~ /#No5./ && $flag == 1) { $flag=0; } print if $flag==1; } close(IN) と書いてみましたが、もっと簡単に書く方法を以前見たことがあったように思うのですが、こう書けばよいのでは?というアイディアがあれば、ご教授いただけないでしょうか?

    • ベストアンサー
    • Perl
  • Perlで行頭にある文字が含まれている行を全部削除して詰めたい

    perl初心者です。以下のようにデータがならんでいる時、 test111 aaaaaaaaabbbbbbbbcccccc test112 aaaaccccabbbbbbbbcccccc test113 aaaaccaaabbbbbbbbcccccc test114 acccaaaaabbbbbbbbcccccc test111 aacaaaaaabbbbbbbbcccccc test112 accaaaaaabbbbbbbbcccccc test113 aaacccaaabbbbbbbbcccccc test114 aaaaaccaabbbbbbbbcccccc test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。 途中からわかりません。 行を削除する関数が調べても見つからないのです。 #!/usr/bin/perl ; open(IN, "test.doc") or die ; open(OUT, ">testout.doc"); while(<IN>) { chomp ; if (/(\S+)/) { $name = $1 ; if ($name =~ /^test112(\S+)/) { #ここでマッチさせて、一気に行を削除して、しかも行を詰めたいのですが ; } print OUT " \n" ; } } close (IN) ; close (OUT) ; 大変困っております。宜しくお願いします。

    • ベストアンサー
    • Perl
  • 全行読み込むには

    open( IN, "pass.dat" ) or die "Can't open pass.dat: $!"; $f_data = <IN>; close( IN ) or die "Can't close pass.dat: $!"; $f_data1 = $f_data; $f_data2 = $f_data; $f_data1 =~ s/<br>//g; $f_data2 =~ s/\S//g; open( OUT, ">log.dat" ) or die "Can't open log.dat: $!"; select OUT; print "$f_data1"; print "$f_data2"; select STDOUT; close( OUT ) or die "Can't close word.js: $!"; 上記スクリプトでは、pass.datの一行目しか読み込まれません。全行を読み込むためにはどのように書き換えればいいのでしょうか?宜しくお願いします。

    • ベストアンサー
    • Perl
  • 指定行に書込み

    open( IN, "log.cgi" ); @f_data = <IN>; close( IN ); $i = '1'; open( OUT, ">dat.cgi" ); select OUT; print "document.open();\n"; print "document.write('"; foreach( @f_data ){ if( $i > 5 ){ last; } ( $f_data1, $f_data2, $f_data3, $f_data4 ) = split( /<>/ ); $f_data1 =~ s/ //g; print "$f_data1"; $i++; } print "');\n"; print "document.close();\n"; select STDOUT; close( OUT ); 上記スクリプトで、指定された行数、又は指定された場所でdat.cgiに 書き出したいのですが、どのように書けばよろしいのでしょうか? 例えば、 ・100行目に書き出す。 または、 ・指定された文字列の間に書き出す。 (例)<!--開始-->ここに書き出す。<!--終了--> このどちらかが出来ればいいのですが、上記スクリプトをどのように変更すれば可能になるでしょうか?お手数ですが、どうぞ宜しくお願いいたします。

    • ベストアンサー
    • Perl
  • Perl。文字出現回数を重複しないでカウントしたい。

    perl初心者です。どうぞ助けて下さい。 以下のようにデータがならんでいる時、 pphhhppphhhppppppphhppppppppppppppppppphhh pが連続した文字の連続数は 2、3、7、19 となります。 今、知りたいのはこのようなpの連続数の出現回数です。つまり、たとえばpが19回連続してあるものは何回でてきたか、が知りたいのです。 上の例だと1回が正解となります。 ところが、スクリプトを書くとき、 たとえば以下のようにしたとき、 pが19回なら重複カウントはなくても、 pを2でカウントしたら、 本当に出てきて欲しいこたえは一回なのに、 P=3、7、19のどれにも該当してしまいます。 #!/usr/bin/perl ; open(IN, "text1.txt") or die ; open(OUT, ">text1out.txt"); while(<IN>) { chomp ; if (/(\S+)/) { $name = $1 ; if ($name =~ /^ppppppppppppppppppp/) { {$count++;} ; } print OUT "$count\n" ; } } close (IN) ; close (OUT) ; 正規表現の中を工夫すればいいのだと思いますが、 大変困っております。宜しくお願いします。

    • ベストアンサー
    • Perl
  • Perl 順位 複数のLoop

    合計の順位を求めたいのですが、 詰まってしまいました。 どうかご教示お願い致しますm(_ _)m まず下記のように Class1 1.txt の 3列目の合計 65.2 2.txt の 3列目の合計 80.5 3.txt の 3列目の合計 70 4.txt の 3列目の合計 92.6 5.txt の 3列目の合計 76.1 6.txt の 3列目の合計 85.2 このように6つのファイルがあり その3列目の合計は求めるとこまできました。 6つのファイルを元に順位をつけて HTMLのテーブル化を試みているのです。 for($Class=1;$Class<=5;$Class++){ open(F, "<","Class$Class.txt"); flock(F, 1); @CL = <F>; close F; for($KakuFile=1;$KakuFile<=$#CL;$KakuFile++;){ open(F, "<","KakuFile/$KakuFile.txt"); flock(F, 1); @DATA = <F>; close F; for($A=0;$A<=20;$A++;){ my $Data = $DATA[$A]; chomp($Data); my ($Name,$No,$Sum,...etc) = split(/,/, $Data); $SumDex = "Sumの合計を求める式"; #1.txt の場合 65.2 #2.txt の場合 80.5 #3.txt の場合 70 $RANK = "ここにどのような記述が入りますか?"; #1.txt の場合 6 #2.txt の場合 3 #3.txt の場合 5 #4.txt の場合 1 #5.txt の場合 4 #6.txt の場合 2 $HTML[$A] =" ~略 <td>$Name</td> <td>$SumDex</td> <td>$RANK</td> ~略 "; @HTML , $HTML[$A]; open(F, ">:utf8","RankHtml.txt") or die("error :$!"); flock(F, 2); print F "@HTML\n"; close F; } } } 最終的な結果としては、 <td>1.txtのName</td> <td>65.2</td> <td>6</td> <td>2.txtのName</td> <td>80.5</td> <td>3</td> <td>3.txtのName</td> <td>70</td> <td>5</td> <td>4.txtのName</td> <td>92.6</td> <td>1</td> <td>5.txtのName</td> <td>76.1</td> <td>4</td> <td>6.txtのName</td> <td>85.2</td> <td>2</td> このような結果がほしいです。 実際やりたいことはこのようなことなのですが、 どうすればいいのかわからず説明も、おかしなとこがあるかもしれません;; どうかお助け願いますm(_ _)m また、初心者で、Loopの使いかたがおかしかったり とかも指摘頂けると幸いです。

  • Perlを使って、大文字小文字関係なく、重複行を削除したい。

    現在、下記のコードで重複行を削除し、ファイルを作成しているのですが、 AAA aaa AaA などのように大文字、小文字が混じっている場合は重複とはみなさず削除の対象になりません。 こういった場合も重複とみなして削除させたいのですがどのようにすればいいでしょうか? open(IN, "INfilename.txt"); open(OUT, ">Outfilename.txt"); while(){ if(!exists($count{$_})){$count{$_}++;print OUT $_;} } close (IN); close (OUT);

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

    いつもお世話になっております. 環境は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

専門家に質問してみよう