こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

テキストデータから指定した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行だけを表示する方法がわからずに困っています。

よろしくお願い致します。

投稿日時 - 2011-07-04 16:38:26

QNo.6853813

すぐに回答ほしいです

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

>フォームに表示させる方法はわかっているんですが、
>クリックで指定した1行だけを表示する方法がわからずに困っています。

「1」「2」「3」をリンクにするならGETで、送信ボタンにするならPOSTでデータをリンク先のCGIなどに送ればいいんじゃないかな。

GETで送るなら、
↓ここを
<TD class="list2">$s_no</TD>

↓こんな感じに変えて、(form.cgiは送り先)
<TD class="list2"><a href="./form.cgi?no=$s_no&name=$s_name&price=$s_price">$s_no</a></TD>


from.cgiで、

my @getdata = split(/'&'/, $ENV{QUERY_STRINGS});
foreach my $s ( @getdata ) {
my @arrdata = split(/'='/, $s);
$h{$arrdata[0]} = $arrdata[1];
}

my $value = join('=', $h{'no'},$h{'name'},$h{'price'},);

print "<input type=\"text\" value=\"$value\">\n";


とかで出来ないでしょうか。
※確認してません。あくまでもヒントなのでコピペでエラーがでたら修正してください。


POSTだと、リンクではなくて"送信ボタン"になると思うので、form.cgi 内の
$ENV{QUERY_STRINGS}
が使えません。

POSTの場合はstdoutを拾う必要があります。(CGI.pmを使うと楽ちんです。)



てか、その一行って、$sdata そのものでしょうから、そもそも$s_XXXXに小分けして送信する必要ないかもしれませんが。。。

投稿日時 - 2011-07-05 12:19:35

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

#3です。

>それぞれ$s_noで番号がふってあるので、
>てっきりform.cgi側でsdeta.txtを読み込んでから、
>クリックした番号$s_noで呼び出す(検索する?)感じで、
>if文かなにかを使って特定の1行を表示させるのかな・・・と思っていたので。

それだと、list表示するためにファイルopen、form表示するためにファイルopen、変更データを書き込むためにファイルopenと、合計3回ファイルをopenすることになります。

対象の一行は、list.cgiで読み込んで変数に格納済みですよね?
フォームを表示するために、form.cgiへ飛んでからもう一度ファイルをopenして読みなおすのは無駄なロジックだと思いませんか?
ファイルの容量とアクセス規模にもよると思いますが、flockも馬鹿にならないので個人的には何度もファイルをopenするのは好きではありません。


[list.cgi]
(1)ファイルを読み込み、それぞれの値を変数化して一覧表示。
(2)リンクをクリックしてform.cgiにそれぞれの変数を送信。(リンク形式ならGETかな?と思いました。)

[form.cgi]
(1)list.cgiから送られてきたデータを、内部で再度変数化。
(2)(1)整形してをフォームに表示する。
(3)”送信”ボタン(<input type="submit">)で、サブルーチンなり別のcgiなりにデータを送ってファイルに書き込む。(ここではPOSTの方が便利)


とやればファイルopenが1回減るかな、と思います。



>また、フォームの内容を書き換えて上書き保存をする場合、
>そのまま「上書き保存」の送信ボタンを押せば
>表示された行だけ書き換えることができるんでしょうか。

ここは、何行目という特定が出来ないのであれば、

open(IN,"../indata/sdeta.txt") || die "$!";
flock(IN, 1);
@data = <IN>;
close(IN);

とやるしかないので、@dataの要素をそれぞれsplitしながらifでの振り分けが必要になると思います。

投稿日時 - 2011-07-06 11:06:39

お礼

回答ありがとうございました。

いちいちファイルopenはしなくても大丈夫なんですね。

まだちょっと完全に理解は出来ていないんですが、
色々なやり方があって、perlは難しいな~と痛感しているところです。

新しく別の仕事が入ってきたので、しばらくcgiのほうは手がつけられそうにないんですが、
koba0626さんから教えてもらった方法でやってみたいと思います。

本当に色々ありがとうございました!
NO.2の回答にベストアンサーをつけさせてもらいますね。

投稿日時 - 2011-07-06 12:51:05

ANo.3

自己レス。^^;;

>my $value = join('=', $h{'no'},$h{'name'},$h{'price'},);

カンマ多すぎ。
my $value = join('=', $h{'no'},$h{'name'},$h{'price'});


>from.cgiで、

form.cgiね。


>POSTだと、リンクではなくて"送信ボタン"になると思うので、form.cgi 内の
>$ENV{QUERY_STRINGS}
>が使えません。

わかり辛い表現になりました。
送信ボタンに関係なく、POSTだと$ENV{QUERY_STRINGS}では拾えません。

投稿日時 - 2011-07-05 12:28:09

補足

色々教えていただいてありがとうございます。
教えてもらったものがうまく作動しないので、今修正しているところです。

その上で質問で申し訳ないんですが、
教えてもらった方法は、リスト一覧で表示された1行を読み取り(?)GETを使ってform.cgiに送るということでしょうか。
この場合、form.cgi側ではsdeta.txtのファイルデータを開かなくても大丈夫なんでしょうか。

毎回補足で申し訳ないんですが、やりたいことは、

sdeta.txtを読み込みlist.cgiでデータ一覧を表示する。
 1 にんじん  150
 2 じゃがいも 200
 3 たまねぎ  100

この「にんじん・じゃがいも」などの名称と「150・200」の金額を編集したいので、
編集したい行の番号をクリックすると、form.cgiにジャンプして、
番号をクリックした1行を名称・金額のそれぞれのフォームに表示させる。
表示されたものを書換え、sdeta.txtに上書き保存。

ということがしたいんです。

それぞれ$s_noで番号がふってあるので、
てっきりform.cgi側でsdeta.txtを読み込んでから、
クリックした番号$s_noで呼び出す(検索する?)感じで、
if文かなにかを使って特定の1行を表示させるのかな・・・と思っていたので。

また、フォームの内容を書き換えて上書き保存をする場合、
そのまま「上書き保存」の送信ボタンを押せば
表示された行だけ書き換えることができるんでしょうか。

本当に初心者で色々とすみません・・・。
会社でcgiを作成していて、色々なHPを参考にちょっとずつ出来上がってはいるんですが、
この「特定の1行」を表示する方法がどうしてもわからないんです(泣)
よろしくお願い致します。

投稿日時 - 2011-07-05 17:32:24

ANo.1

正確にどこがわからんのかがわからんのだけど, ハッシュ (か配列) に突っ込んじゃえばデータはとってこれるよね.

投稿日時 - 2011-07-05 00:14:21

補足

説明がわかりずらくてすみません。

そのデータのとってきかたがわからなくて困っています。

複数の行があって、最初から「3行目を取り出したい」とかわかっているなら処理はなんとなくわかるんですが、
そのつどクリックした特定の行をどのように表示するのかがわからないんです。

表示する側のcgiでtxtファイルを開く・・・までもちろんはわかるんですが、

open(IN,"../indata/sdeta.txt");
@data = <IN>;
close(IN);

この後の処理がわかりません。

$s_noに入っている数字を検索して表示するんでしょうか?

ここ数日、本当にわからなくて頭を抱えています。
よろしくお願い致します。

投稿日時 - 2011-07-05 09:58:48

お礼

色々勉強したいと思います。
ありがとうございました。

投稿日時 - 2011-07-06 12:51:50

あなたにオススメの質問