ファイルデータの入れ替えについての質問

このQ&Aのポイント
  • ファイルデータの入れ替えについての質問です。POSTメソッドで送られてきたデータ$get_yearと$get_monthが、ファイルの中のデータと一致する場合はその行を入れ替え、一致しない場合は追加して書き込む処理を行いたいです。
  • ファイルデータの入れ替えについての質問です。処理の流れとしては、POSTメソッドで送られてきたデータ$get_yearと$get_monthが、ファイルの中のデータと一致する場合はその行を入れ替え、一致しない場合は追加して書き込むという処理を行いたいです。
  • ファイルデータの入れ替えについての質問です。ファイルの内容は$s_get_year<>$s_get_month<>@chk<>という形式で並んでおり、POSTメソッドで送られてきたデータ$get_yearと$get_monthが一致する行を入れ替えたり、追加したりしたいです。
回答を見る
  • ベストアンサー

ファイルデータの入れ替えについての質問

お世話になります ファイルの内容は $s_get_year<>$s_get_month<>@chk<>\n このような並び方です POSTメソッドで送られてきたデータ$get_yearと$get_monthが 一番目のデータ($s_get_year)と2番目のデータ($s_get_month)と同じならば その行を入れ替えて、そうでなければ追加して書き込むという処理を行いたいのですが 下記のようにしたのですが思い通りの動作をしません、御教授お願いします。 sub ho_disc_write { @new=(); open(IN,"$holidayfile") || &error("Open Error : $holidayfile"); while (<IN>) { ($s_get_year,$s_get_month) = split /<>/, $_, 2; if ($s_get_year == $get_year && $get_month == $s_get_month) { $_ = join('<>',$get_year,$get_month,@chk,"\n"); } push(@new,$_); } close(IN); # データ上書き open(OUT,">$holidayfile") || &error("Write Error : $holidayfile"); print OUT @new; close(OUT); exit; }

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

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

  • ベストアンサー
  • moon_piyo
  • ベストアンサー率60% (88/146)
回答No.3

ん~今回の質問に関係あるところだけ... split関数は3つの引数を与えることができます split /pattern/, expr, limit expr という文字列を /pattern/という正規表現にマッチするデリミタで分割し 分割された部分文字列をリストとして返します limitが与えられた場合は最大 limit個の文字列に分割します(注 limit>0の場合です) #sample 1. $var = "One:Two:Three"; @list = split( /:/ , $var ); これは $var という変数の内容を /:/ にマッチする文字(この場合は:のみ)で分割し,分割された部分文字列のリストを返します $varの内容は変化しません。 順を追ってみていきますと Oneの直後の:で「One」 「Two:Three」 (2つの文字列に分割) Twoの直後の:で「One」 「Two」 「Three」 (3つの文字列に分割) もう:がないので分割は完了です 結局('One','Two','Three')というリストを返します #sample 2. $var = "One:Two:Three"; @list = split( /:/ , $var, 2); limitとして2が与えられた場合,$varの値を:で分割していくのは上と同じなのですが,2つの部分文字列に分けることができた時点で分割をやめちゃいます 順を追っていきますと Oneの直後の:で「One」 「Two:Three」 (2つの文字列に分割) ここで分割はストップ 戻り値としては('One','Two:Three')となります あと今回の質問とは関係ないかもしれませんが limitを与える場合と与えない場合の違いとして.. @a = split(/:/, "One:::",4); # 結果 @a = ('One', '', '', ''); @a = split(/:/, "One:::"); # 結果 @a = ('One'); (limitを与えないとリストの最後の空の要素は切り捨て)

goodjob_001
質問者

お礼

お世話になります、分かりやすく詳しい解説ありがとうございます 大変良く理解できました。

その他の回答 (2)

  • moon_piyo
  • ベストアンサー率60% (88/146)
回答No.2

($s_get_year,$s_get_month) = split /<>/, $_, 2; ↓ ($s_get_year,$s_get_month) = split /<>/, $_, 3;

goodjob_001
質問者

補足

moon_piyoさんありがとうございますいつも世話になっております 動作確認出来ましたが、この場をお借りしてsplit関数の使い方を教えて頂けませんでしょうかたとえば $var = "One:Two:Three"; @list = split( /:/ , $var ); @listは$varという文字列の中の:を,に置き換えるという書き方は理解できるのですが ($s_get_year,$s_get_month) = split /<>/, $_, 3; このスクリプトですと<>を$_に置き換える即ち<>を消してしまう動作という理解の仕方で宜しいのでしょうか?またその後の3という数字の意味が理解出来ないのですが すみませんが宜しく御教授お願いいたします。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

何がどう「思い通り」じゃないのかを補足した方が、回答が付きやすいと思います。 追加が上手くできないというのだったら、ifが一度も成立しない場合のロジックが抜けているせいかと。

参考URL:
http://www.hyuki.com/writing/techask.html#realresult
goodjob_001
質問者

補足

すみません、説明の不足のようでした。

関連するQ&A

  • ログファイルの指定行に書込み

    open(IN,"$log") || &error("Open Error"); @data = <IN>; close(IN); while (100 <= @data) { pop(@data); } open(OUT,">$log") || &error("Write Error"); print OUT "$in{'id'}<>$in{'comment'}\n"; print OUT @data; close(OUT); ログにはID、時間、コメントが登録されています。 送信データの中に、ログに登録済みのIDがある場合には、そのIDのある行のみを書き換えたいのですが、方法がどうしてもわかりません。 $logに記録されるIDの順番は以下のようにランダムです。IDに登録される文字列は1からの数値のみです。 52<>コメント 120<>コメント 35<>コメント 8<>コメント 2<>コメント 19<>コメント 85<>コメント よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • データの入れ替え処理が巧くできないのですが

    いつもお世話になります 簡単なDBを作っているのですが、データの更新処理が巧くいかなくててこずっています POSTメッソドで送られてきた name=actionの内容がedit2、の時 sub menteが実行されます同じく name=noの変数には更新したいファイルの番号がセットされます それらを取得して、ファイルを開き $nooの内容(DBのファイル番号)とnoが一致したらブラウザから送られてきたデータと その部分のデータ($nooはデータの先頭で以降<>で区切って変数が格納される) を入れ替える処理を行いたいのですがどの様に書いたらいいのでしょうか、下記のコードですと変数 $_に更新される前のデータしか代入できず結果ファイルの入れ替えは行えません open(IN,"$logfile") || &error("Open Error : $logfile"); while (<IN>) { ($noo,@arg_[0..$#eqipument],@p[0..5],$n_article,$w_article,@reselect_marks) = split /<>/; if ($no == $noo ) { $_ = join('<>',$noo,(map{$arg_[$_]}(0..$#eqipument)),$p0,$p1,$p2,$p3,$p4,$p5,$n_article,$w_article,@reselect_marks,),'<>',"\n"; } push(@new,$_); } close(IN); # 更新 open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); 尚ブラウザから送信されてくるデータは以下のような感じです print qq|<form action=\"$myself\" method=\"POST\">\n|; print qq|<input type=hidden name=mode value=\"admin\">\n|; print qq|<input type=hidden name=action value=\"edit2\">\n|; print qq|<input type=hidden name=no value=\"$no\">\n|; 宜しく御教授お願いいたします。

    • ベストアンサー
    • Perl
  • ログファイルの記録数

    # ログ更新 unshift(@new,"$num<>$addr\n"); open(OUT,">$logfile") || &error("Write Error: $logfile"); print OUT @new; close(OUT); 上記ログの書込みに、最大保存数を設定したいのですが、どのようにすればいいのでしょうか。 $max = 3; とした場合、3行超えたら古いファイルを消したいと考えています。よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • CSVデータの編集の際の重複チェックの方法

    今、data.csv(カンマ区切り)として、左から順位、名前、性別という3項目で、10人程度のリストデータがあります。 data.csv(カンマ区切り)を編集するようにしていますが、順位は重複してはならないので、重複していたらエラーを出したいのですが。。。 ($rank,$name,$sex) = split(/\,/,$line); です。 open(IN,"$logfile") || &error("ファイルが開けません"); @lines = <IN>; close(IN); # 情報の書換え foreach $line (@lines) { ($rank,$name,$sex) = split(/\,/,$line); $line = "$in{'rank'},$name,$sex\n";} push(@new,$line); } # ファイルを更新 open(OUT,">$logfile") || &error("ファイルが開けません"); print OUT @new; close(OUT);

  • if文データの別ファイル化について

    金星と火星の「○年○月○日は○座」というのがわかっていて, それを入力された年月日と比較して答えを出してるのですが、 数年間のデータを全部if文で書くと,分量が非常に多くなって しまいます。 そこで、金星と火星それぞれのデータを別ファイルにしてしまう 方法はないでしょうか?初心者なもので、なるだけ具体的に よろしくお願い致します。 以下ソースコードです。 #以下金星のデータ sub get_venus_data{ local($year,$month,$day)=@_; local($horoscope)='データなし'; if($year==1950){ if($month<=3 || ($month==4 && $day<=6)){ # ~4月の6日以下 $horoscope = 'みずがめ'; # みずがめ座 }elsif($month==4 || ($month==5 && $day<=5)){ # 4月の残り~5月の5日以下 $horoscope = 'うお'; # うお座        ・        ・       間省略        ・        ・ }elsif($month==12){ # 12月の残り~12月の31日以下 $horoscope = 'やぎ'; # やぎ座 } } return $horoscope; } #以下火星のデータ sub get_mars_data{ local($year,$month,$day)=@_; local($horoscope)='データなし'; if($year==1950){ if($month<=3 && $day<=28){ # ~3月の28日以下ならば $horoscope = 'てんびん'; }elsif($month==3 || ($month==6 && $day<=11)){ # 3残り又は6/11以下 $horoscope = 'おとめ';        ・        ・       間省略        ・        ・ }elsif($month<=12){ # 12残り $horoscope = 'みずがめ'; } } return $horoscope; } # 入力から金星と火星の星座を求める。 $venus = get_venus_data($in{'year'}, $in{'month'}, $in{'day'}); $mars = get_mars_data($in{'year'}, $in{'month'}, $in{'day'});

    • ベストアンサー
    • CGI
  • perlでファイルのデータの一部を削除したい

    久しぶりにPerlを操作してファイルのデータの一部を削除したいのですが、削除出来ずに困っております。 3年以上触っていないため、過去のファイル等々を見ながらやってましたが、結果は出来ずじまいで停滞して困っております。 ご指導いただけないかと思い、書き込みしました。 ファイル名 $tmpfile データ構成  no,名称 1<>フレーム 2<>レンズ 3<>カメラ 4<>ファインダー 5<>めがね 6<>ズーム これで「めがね」を削除したいのです。 データnoで削除したいと思っておりますが、うまく動作しません。 以下ソース open(DB,"$tmpfile") || &error("Open Error : $tmpfile"); flock(DB, 1); @lines = <DB>; @new=(); foreach $line (@lines) { $flag=0; ($no,$meisyo) = split("<>", $line); foreach $x (@DEL) { if ("$x" eq $tmpnum) { $flag=1; last; } } if ($flag == 0) { push(@new,$line); } } open(OUT,">$tmpfile") || &error("Write Error : $tmpfile"); print OUT @new; close(OUT); ここまで 上のソースですと、エラーこそならずに(そうみえているだけかもしれません)終わりますが、データ削除が正しく出来ませんでした。 説明不足があるかもしれませんので、指摘いただけますと幸いです。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • socketでのバイナリファイルの扱い方

    javaのsocketを用いてファイルの送信サーバ、受信クライアントを作成しているのですが テストプログラムとしてスレッド化せずに送信・受信部のみ作りました。 症状はバイナリデータの転送がうまくできないことです。ソースを抜粋すると サーバ側で BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());//socketはSocketクラス BufferedInputStream in1 = new BufferedInputStream( new FileInputStream("test1.bmp")); BufferedInputStream in2 = new BufferedInputStream( new FileInputStream("test2.bmp")); while( (c = in1.read() ) != -1 ){   out.write(c); } while( (c = in2.read() ) != -1 ){   out.write(c); } クライアント側で BufferedOutputStream out1 = new BufferedOutputStream( new FileOutputStream("test1.out.bmp") ); BufferedOutputStream out2 = new BufferedOutputStream( new FileOutputStream("test2.out.bmp") ); BufferedInputStream in = new BufferedInputStream( s.getInputStream() ); while( ( c=in.read() ) != -1 ){   out1.write(c); } while( ( c=in.read() ) != -1 ){   out2.write(c); } とやっています。 クライアント側で1回目のin.readを抜けるときにはサーバ側は既に2回のwriteを終わっているようで ファイルはtest1.out.bmpにマージされていました。 サーバ側の1回目のwriteのオブジェクトがcloseしていないことが原因だと思い1回目のwriteが終わった時点でout.close()とした のですがそうやるとsocketも閉じてしまいsocket closeのエラーが生じてしまいました。 このようにならず1本のコネクションでバイナリのデータを複数送信する方法をご存知でしたら教えてください。 [環境] win2ksp1a,j2sdk1.4.1_03,java経験4ヶ月程度

  • 配列のデータから改行だけを取り除いて上書きしたい

    いつもお世話になっています。 CGIで現在下記のようなファイルがあります。 【sample.cgi】 1<>2<>3<>4<>5<> 6<>7<> これを下記のスクリプトで呼び出し配列に入れます。open(IN,"./sample.cgi"); @DATA = <IN>; close(IN); @data = split(/<>/,$DATA[0]); @N_DATA=(); unshift(@N_DATA,"$data[1]<>$data[2]<>$data[3]<>$data[4]<>$data[5]<>$data[6]<>$data[7]<>"); open(OUT,">./sample.cgi") or &error('書き込み失敗'); print OUT @N_DATA; close(OUT); しかし実行結果は改行が残ったままで、どうにか 1<>2<>3<>4<>5<>6<>7<> という形で出力したいのですがどのように変更を行えば宜しいでしょうか。 恐らく「unshift」の部分が行を追加していっていると思うのですが、printなどで出力するとsample.cgiの中身が空になってしまい・・・。 「読み込むデータに改行があった場合は改行を削除して読み込む」という動作をさせたいのですが・・・。 何卒よろしくお願い致します。

    • ベストアンサー
    • CGI
  • データ件数が多くなってもエラーにならない方法

    perlで、URLからサイトが表示されるかを確認するプログラムを作成しました。 ただ現在の方法だと、チェックするデータ件数が多くなるとエラーとなってしまいます。 現在のソース (ここから) open(DB,"$memfile") || &error("Open Error : $memfile"); flock DB, 2; @lines = <DB>; close(DB); @new=(); foreach $line (@lines) { $flag=0; ($num,$url,$title) = split("<>", $line); &url_ckeck("$url"); $data = "$num<>$url<>$title\n"; $data =~ s/\n<>/<>/g; $data =~ s/\r\n<>/<>/g; $data =~ s/\r<>/<>/g; push(@new,$data); } open OUT, "> $memfile"; print OUT @new; close OUT; (ここまで) この方法だと300件を超えると「ページが表示出来ない」エラーがでてしまうので、 チェックの方法を小分けしてエラー回避できないかを考えているのですが、とのようにすれば良いのかがわからず先に進められなくなってしまいました。 プログラムも見よう見真似で作成しているのでおかしな箇所が多々あるかと思いますが、助けていただけないかと思い書き込みました。 「$line (@lines)」を「$start .. $end」として件数を小分けにしてボタンを表示させてクリックして進められるようにしてみたらとも思いましたが データがうまく更新出来ずにいます。 不明点はご指摘ください。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • ファイル読み込み/書き込み速度を上げるには

    下記のようなファイルの読み込み/書き込み処理において、もっと効率よく(速く)読み込み・書き込みをしたい場合どのような工夫をすれば良いでしょうか? BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("sample2.data")); BufferedInputStream in = new BufferedInputStream(new FileInputStream("sample1.data")); int c ; while((c = in.read()) != -1) { out.write(c); } in.close(); out.flush(); out.close();

    • ベストアンサー
    • Java

専門家に質問してみよう