- 締切済み
ファイルの中の配列データの変更
以下の内容のファイル A.datがあります。 "34"-"情報処理" "87"-"会計" "99"-"社会学" [EOF] いま、"87"と"医学"という値がPerlの引数で与えられたとして "87"-"会計" → "87"-"医学" というふうに置き換えたいのです。 "87"と一致する行を配列に読み込むことはできました。 "87"-"会計"の"会計"も読み出せます。"87"-"医学"にも置換でき ます。しかし、それを元のファイルA.datにそこの部分だけを 変更して書き戻すことができません。 どのようにしたらよいのでしょうか。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- g_p_
- ベストアンサー率53% (28/52)
試しに、適当な一時ファイルに書き出して、 最後に rename するってのはどうですか? 以下の様な感じで。 #! /usr/bin/perl use strict; use warnings; my $source_file = 'A.dat'; my $temp_file = 'B.dat'; my $arg_number = $ARGV[0] || 87; my $arg_name = $ARGV[1] || '医学'; open my $source_fh , '<' , $source_file or die $!; flock $source_fh , 1 or die $!; open my $temp_fh , '>' , $temp_file or die $!; flock $temp_fh , 2 or die $!; while (<$source_fh>) { if ( my( $name ) = /^"$arg_number"-"([^"]*)"/ ) { s/$name/$arg_name/; } print {$temp_fh} $_; } close $source_fh; close $temp_fh; unlink $source_file or die $!; rename $temp_file , $source_file or die $!; __END__ どこでコケるかで、権限の問題とかも把握しやすいのでは? (注)データによって正規表現はもう少し考える必要があるかもしれませんね。
- okok_tone
- ベストアンサー率0% (0/2)
ファイルに出力できないのであれば、その保存対象となるディレクトリに CGIがファイルを出力する権限があるのかを、確認したほうが良いとおもいます 一度サーバ管理者(業者?)に確認してみてはいかがでしょう 補足ですがファイルを出力した後にパーミッションを変更する記述も 付け加えたほうがいいです(念のため) ・ ・ close(OUT); # closeすれば自動でロック解除 chmod(0777, "./a.dat"); #パーミッションを777に変更 undef(@new_data); undef(@item); 以上です
- okok_tone
- ベストアンサー率0% (0/2)
my $param1 = "87"; #引数1。 my $param2 = "医学"; #引数2。 #ファイルを読み出す。 open(IN,"./a.dat"); flock(IN,1); #ファイルを読み出しロック。 my @item = <IN>; flock(IN,8); #ロック解除。 close(IN); my @new_data = (); #新規データ初期化。 foreach my $item(@item){ chomp($item); #改行削除。 my (@temp) = split(/-/,$item); if($temp[0] eq "\"$param1\""){ push(@new_data,"$temp[0]\-\"$param2\"\n"); }else{ push(@new_data,"$item\n"); } } #ファイルを書き出す。 open(OUT, "> ./a.dat"); # 読み書きモードで開く flock(OUT, 2); # ロック確認。 seek(OUT, 0, 0); # ファイルポインタを先頭にセット print OUT @new_data; # 書き込む truncate(OUT, tell(OUT)); # サイズを書き込んだサイズにする close(OUT); # closeすれば自動でロック解除 undef(@new_data); undef(@item); こんな感じでできませんか? ちなみにホントは全部読んでくるよりも、一行ずつ処理をした方がいいんですけどね(メモリ関係で) う~~ん、我ながら泥臭いプログラムだ。。
- sakusaker7
- ベストアンサー率62% (800/1280)
結局のところ、丸ごと書き直すしかありません。 ファイルというのはそういうものなので (今回の場合は書き換える前と後で長さが変わらないので ごにょごにょできなくもありませんが)。 一応こういうモジュールもあるみたいですけど File::Inplace - Perl module for in-place editing of files - search.cpan.org http://search.cpan.org/~chipt/File-Inplace-0.20/lib/File/Inplace.pm use File::Inplace; my $editor = new File::Inplace(file => "file.txt"); while (my ($line) = $editor->next_line) { $editor->replace_line(reverse $line); } $editor->commit;
- calltella
- ベストアンサー率49% (317/635)
「A.dat」が何行あるのかわかりませんが 全部を読み込んで書き換えてから 全部を書き込みではダメなんでしょうか?
お礼
回答ありがとうございます。 全部を読み込んで書き換えてから 全部を書き込みのプログラムの例を みせていただけないでしょうか。
お礼
回答ありがとうございました。 この通りにしたんですが、ファイルに書くことがやはり できませんでした。どこがおかしいのでしょうか。