Perl コーディング初心者質問コーナー Part26
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
03/07/24 19:48ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
関連スレ
【Perl上級者コーナーPart01】
http://pc2.2ch.net/test/read.cgi/php/1024741312/
CGI: Common Gateway Interface part 11
http://pc2.2ch.net/test/read.cgi/php/1055597189/
【Perl,CGI】参考書籍 第三版
http://pc2.2ch.net/test/read.cgi/php/1030209573/
【 スクリプト改造工房 PART 6 】
http://pc2.2ch.net/test/read.cgi/php/1047806915/
過去ログやお勧めサイトは >>2-10
0110nobodyさん
03/07/26 12:19ID:???行数も減って処理の流れが読みやすくなるし
0111106
03/07/26 12:33ID:???>>110
別ファイルということは、やっぱりrequire文でhtmlを出力するためのスクリプトを
呼び出すということでしょうか?
いろいろとあたっている時に、>>106で例に挙げているようなスクリプトで
TITLEタグの内容を変数で与えてあげられるようにしているのをよく見てまして、
やっぱり処理部分と出力部分は分けたほうがいいのでしょうねぇ、と思っては
います。
ちなみに別ファイル内でのhtml部分のインデントはどうされていますか?
0112nobodyさん
03/07/26 12:36ID:???またはprintの部分だけインデントしないとか。
0113106
03/07/26 12:36ID:???デバッグ終了時に、出力時に不要な文字を消す処理を有効にする、という事ですか?
ちなみにそうなると、完成版が出力するHTMLはインデント無しですか?
0114nobodyさん
03/07/26 12:45ID:???そうですね。ヒアドキュメントも考えてみたのですが、bash等で使えるような
空白+終端文字列(<<-でしたっけ?)等が無さそうで、難儀しています…
0115nobodyさん
03/07/26 12:58ID:???ファイルオープン→読む→出力→ファイルクローズだと思うけど。
>>114
bashでシェルスクリプト組んでるの?
ちょっと良くわからない。。
0116nobodyさん
03/07/26 13:12ID:???> ファイルオープン→読む→出力→ファイルクローズだと思うけど。
それだと、外部ファイルをそのまま出力という形になって、例えばファイル中に
変数を仕込んでおいて、その変数の値を表示させる…等という事をしたい場合、
何か上手い方法はありますか?sed的な置換を駆使でしょうか?
> >>114
> bashでシェルスクリプト組んでるの?
実はOSがVineLinux2.6R1でして、/bin/sh -> bashとなっているので…
0117109
03/07/26 13:15ID:???>ファイルオープン→読む→出力→ファイルクローズだと思うけど。
これと同じようにしてる。
ただ、やや複雑になってきたりするとやっぱプログラム内で生成する。
ループでテーブル生成、ってのを多用するから。
ヒアドキュメントは、絶対左側に書くって規則があるから使わない。
しかもヒアドキュメントだと状況によって細かく出力を変えれないからあんま使い道ない気が…。
ヒアドキュメント使うなら外部にHTMLを書いたtxtを置くかな。
>別ファイルということは、やっぱりrequire文でhtmlを出力するためのスクリプトを
>呼び出すということでしょうか?
プログラム内でHTMLを生成する必要がある上、あまりに縦長で邪魔になった時は、
こーゆーのも作った事あるよ。俺は。
0118nobodyさん
03/07/26 13:30ID:???変数だってリファレンス使えばいいし
0119あぼーん
NGNG0120115
03/07/26 14:02ID:???独自なタグとか作って置換、splitで切り張りとか。
書き換える部分が一点に集中してる(単一テーブルなど)の場合、
二つのファイル(ヘッダ部とフッタ部)を作ったり。
>>117
>ヒアドキュメントは、絶対左側に書くって規則があるから使わない。
変数に入れれば、思いのままに整形できるよ。
クックブックのレシピ1.11
0121115
03/07/26 14:37ID:???連続カキコ失礼。
0122nobodyさん
03/07/26 18:21ID:???perldelta
http://www.att.or.jp/perl/change/5004pre.html
http://www.kt.rim.or.jp/~kbk/perl5.005/perldelta.html
0123nobodyさん
03/07/26 23:22ID:UhENImdiどこで配ってたか忘れてしまいました。
ぐぐったものの見つからず。
どなたかご存じだったら教えてください。
0124nobodyさん
03/07/26 23:34ID:P3xPXFZK&& $gg < 71 && $fd < 71 && $ar < 71 && $ss < 2500 ){
を書きました。
ちょっと長いから難しいかなあと思って一通りテスト
したんですが、なんと全部正しかったです。
しかし、やはりプログラム処理も間違える事
はあるんでしょうか?
0125nobodyさん
03/07/26 23:36ID:???ある程度、グローバルスタンダードというか、
おきまりの付け方って存在するんでしょうか?
0126nobodyさん
03/07/26 23:47ID:???ActivePerl ならインストールしたディレクトリ以下に入っているかも知れない。
>>125
http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlstyle.html
0127nobodyさん
03/07/27 02:46ID:???これはHTMLだとコメントになりむしされる。
これを利用して、このように。
$hoge = "seiseishitai html no naiyou";
$hogehoge = "mouhitotsu seisei shitai html no naiyou";
open TEMP,"/path/to/template.html">
while(<TEMP>){
s/<!HOGEHOGE>/$hoge/g;
s/<!HOGE>/$hogehoge/g;
print;
}
0129nobodyさん
03/07/27 04:00ID:???だった。
0130nobodyさん
03/07/27 09:21ID:???ない。「それにはいくとおりもやりかたがある」から。
C言語出身のやつはC言語での命名規則を、
Java出身のやつはJavaでの命名規則を、
使えばそれでいい。
0131nobodyさん
03/07/27 09:51ID:???全部大文字のsubも使わないほうが良かったような。
0132nobodyさん
03/07/27 11:40ID:qAaynntQforeach(split(/&/,$query)){略}
とした場合、splitは1回だけ実行されるのでしょうか。
ループのたびに実行されてたら馬鹿みたいなので。
0133nobodyさん
03/07/27 11:47ID:???0134132
03/07/27 11:54ID:???くだらない質問失礼しました。
0135あぼーん
NGNG0136あぼーん
NGNG0137nobodyさん
03/07/27 14:00ID:???なんで最近こんな奴ばっかなんだよ。
>splitは1回だけ実行されるのでしょうか。
他人に聞くよりPerlに聞いた方が正確だし早い。やればわかるだろ。
0138nobodyさん
03/07/27 17:20ID:LVhmum4F件数を先に出力したいから、
$n=0;
open(DATA,"data.txt");
foreach(<DATA>){
if($_ =~ m/$keyword/){ $n+=1; }
}
print "$n件見つかりました。<br><br>";
close(DATA);
open(DATA,"data.txt");
foreach(<DATA>){
if($_ =~ m/$keyword/){ print "$_<br>"; }
}
こうやってるんですが、2回データ開くってのが、ソースが変だし、効率が悪いと思うんですが、効率いい方法ありませんか?
「件数」を先に出力するので、この方法以外考えられません。
条件に当てはまったものを、配列に入れて、後で出力ってのも考えましたが、
配列は効率わるそうで・・・
ご教授お願いします
0139nobodyさん
03/07/27 17:22ID:???とかストッパーかけておくと良い。
0140nobodyさん
03/07/27 17:25ID:???if ( 表示する条件 ) { continue; }
$n++;
if (??) { contine; }
if(??) { contine; }
print $_; or $xx = $_;
}
$n件見つかりました
結果$xx
0141nobodyさん
03/07/27 17:27ID:???if(??) { contine; }
↑ゴメン s/contine/last/g
ついでに、ここは表示するページのはじめの数から後の行数を先に求めておく。
0142nobodyさん
03/07/27 17:45ID:LVhmum4Fゴメン。難しくて理解できない・・・
ちょっと解説お願いできますか?
0143nobodyさん
03/07/27 17:54ID:???0144nobodyさん
03/07/27 17:59ID:???メモリは食うだろうが。
0145nobodyさん
03/07/27 18:09ID:???open(DATA,"data.txt");
while(<DATA>){
if($_ =~ m/$keyword/){ $n+=1; $str .= "$_<br>"; }
}
close(DATA);
print "$n件見つかりました。<br><br>$str";
これじゃだめなのん?
オープン2回が気になるなら、seekで戻せば開きなおす必要はなし。
0146nobodyさん
03/07/27 18:15ID:???$n=0;
open(DATA,"data.txt");
while(<DATA>){
if(/$keyword/o){
push(@hit, $_);
$n++;
}
}
print $n. '件見つかりました。<br><br>';
foreach(@hit){
print $_. '<br>';
}
close(DATA);
んじゃ、配列使うやつ。
DATAファイルハンドルは避けたほうがいいよ。
改行もしっかり処理しよー。
0147nobodyさん
03/07/27 19:03ID:bAtOJVkaBというサーバーでは動きません。
原因として考えられるのって何があるでしょうか?
0149nobodyさん
03/07/27 19:25ID:???0150nobodyさん
03/07/27 19:58ID:LVhmum4F効率は悪くないんですかね・
>>145>>146
ありがとうございます。
ソートもできたらなぁ、と今思っていたので配列にすることにします。
どうもありがとうございました
0151あぼーん
NGNG0152あぼーん
NGNG0153nobodyさん
03/07/27 20:59ID:???文字列として $str .= $_;
ってやったほうが良いでしょう。
0156(*゚p゚)Chan ◆ClChang/Go
03/07/27 22:01ID:???(*゚p゚)σ違うにゃりよ!!!
ε=ε=ε=┌(*゚p゚)ノ サササッ
0157nobodyさん
03/07/27 22:11ID:???0158nobodyさん
03/07/27 22:14ID:???0159nobodyさん
03/07/27 22:16ID:???スクリプトなのですが、どのへんまでたまったら古いログを消していくべきか
こまっています。
たとえば1MBのログファイルを開け閉めするのと10KBのログファイルを開け閉めするので
処理時間に差が出たりするのでしょうか?
0160nobodyさん
03/07/27 22:41ID:???>たとえば1MBのログファイルを開け閉めするのと10KBのログファイルを開け閉めするので
>処理時間に差が出たりするのでしょうか?
聞く前に試せよ。その試した結果に疑問があるなら質問しに来い。
0161nobodyさん
03/07/27 22:42ID:???あるんじゃないの?
何のアクセスログか知らないけれど、
ログを切る方法なんていろいろあるでしょ。
apacheのログ?
rotatelogs。。
logrotate。。。
あるいはシェルとか。
0162nobodyさん
03/07/27 22:48ID:???アペンドなら有意な差(特に1Mと10Kなら)はないと思う。実測した事ないので>>160が言ってるように
測定して報告してくれ。
0163nobodyさん
03/07/27 22:57ID:???いえ、apacheのじゃなくてよくある画像を用いたアクセスログです。
あくまで一般的な知識としてどうなのか、と思って訊いてみたんですが。
測定する方法を考えて出なおしてきます。
0164nobodyさん
03/07/28 00:32ID:???DProfとかあんだろ。
0166nobodyさん
03/07/28 01:03ID:???0167159
03/07/28 04:46ID:???空のファイルに対してopen(FH,">>$file")でlocaltimeを書き込んでいくループを
やらせてみたら、ファイルサイズが100KBだろうか1MBだろうが10MBになろうが
処理のスピードは変化無しでした。
まあ考えてみたら>>で書き込むのってファイルを開いてポインタを末尾に移動して
書き込むだけだから、そのファイルが小さかろうが大きかろうが関係無いっぽいけど。
ちなみに同じことを毎回行を配列化→pushで追加→>で新規書き込みっていう
ループでやってみたら、当然処理はだんだん遅くなりました。
16[4-5]のモジュールは使い方よくわかりませんでした。
0168nobodyさん
03/07/28 06:36ID:+imB0DDxサーバー上に掲示板のログが大量にあります。
これらを小さくまとめる&転送速度を上げるために、gzipで圧縮して閲覧可能にしたいと思っています。
gzipの圧縮は1度行えばいいので、Windows上かシェルで行い、サーバー上に置いておくことになりますが、
そのファイル名が、$FORM{url} だとすれば、
print "Content-type: text/html;charset=Shift_JIS\n";
unless($ENV{'HTTP_ACCEPT_ENCODING'} =~ /gzip/){&error($FORM{url}); exit; }
if($ENV{'HTTP_ACCEPT_ENCODING'} =~ /x-gzip/){ print "Content-encoding: x-gzip\n\n"; }
elsif ($ENV{'HTTP_ACCEPT_ENCODING'} =~ /gzip/){ print "Content-encoding: gzip\n\n"; }
if (!open(GURL,"<$FORM{url}")){ &error(1); exit; }
binmode GURL;
@gzipdata = <GURL>;
close(GURL);
print @gzipdata;
exit;
#エラーの場合はURLをリンクで示してダウンロードしてローカルで解凍してもらうよう表示する。
こうなるのかと、とりあえず書いてはみたものの、一度メモりに読むのは避けられないのか、
バイナリ扱うPerl書いたことないからこれでいいのか。
あるいはもっと効率的な方法をご存じの方は教えてください。
0169nobodyさん
03/07/28 11:36ID:???後ろから処理するということはできないでしょうか?
while( <FILE> ) { 処理 }
配列などに入れてしまえばできるのですが、メモリとしてはこちらの方がよいと
思いまして、どうかよろしくお願い致します。
0170nobodyさん
03/07/28 11:44ID:???逆順は難しいと思われ。
一行のバイト数が固定なら色々とやりようもあるだろうが。
可変行の場合、俺はやり方を知らない。
配列でやるんだったら配列の入れ方を工夫するといいかも。
@data = <FILE>;
@data = reverse(@data);
とやるよりも
@data = ();
while(<FILE>){unshift(@data);}
とした方がいいかもしれない。
0171nobodyさん
03/07/28 11:45ID:???0172nobodyさん
03/07/28 12:04ID:???試してないけど。
binmode STDOUT;
my $CRLF = "\x0d\x0a";
my $encoding = $ENV{'HTTP_ACCEPT_ENCODING'};
print 'Content-Type: text/html; charset=Shift_JIS', $CRLF;
$encoding =~ /gzip/ or &error($FORM{url}, exit;
open GURL, '<' . $FORM{url} or &error(1), exit;
if ($encoding =~ /x-gzip/) { print 'Content-Encoding: x-gzip', $CRLF }
elsif ($encoding =~ /gzip/) { print 'Content-Encoding: gzip', $CRLF }
print $CRLF;
print while read GURL $_, 1024; # LENGTH は適宜調整
close GURL;
>>169
http://www.din.or.jp/~ohzaki/perl.htm#File_Reverse
0175nobodyさん
03/07/28 13:21ID:ZypqctSD例えば同じ変数をどこのサブルーチンで使いたい場合はどうするんでしょうか。
いちいち変数の受け渡しをしないといけないんでしょうか。
0177nobodyさん
03/07/28 13:47ID:???174が言ってるように、ファイル名に.gz追加
logfile1.html.gz
HTTP_ACCEPT_ENCODING見てサーバがファイルを選んでくれる。
0178nobodyさん
03/07/28 13:49ID:mZs5gojbour。バージョン古くて使えなければuse vars。
0179nobodyさん
03/07/28 13:52ID:???妙な静的変数
{
my $static;
sub hoge {
}
sub hogehoge {
}
sub hagehage {
}
}
0180nobodyさん
03/07/28 14:33ID:MPvwsvte確認ボタンでその画像がブラウザで確認出来るようにしたいのですが、
良い方法ないでしょうか?
0182nobodyさん
03/07/28 14:41ID:???> 16[4-5]のモジュールは使い方よくわかりませんでした。
使えるようになると便利だぞ。
面倒かもしれんけど、ぐぐってみるなりして使いこなせ。
>>180
送信する前にプレビューってことか?
JavaScriptでフォームからファイルパス取って、IMGに埋め込むとか。
できるかわからんけど。
とりあえずスレ違いなので詳細はそれ系スレで。
0183nobody
03/07/28 21:25ID:0jEUdWDa「じゃんけん」ができるプログラムを作りたいんだけど
何かいい方法ありますか?
当方かなり初心者なんで
print"〜";#って文字を出力することしかできないんですけど。
えーと質問の意味がわからなかったらスルーしてもらってもかまいません。
0184あぼーん
NGNG0185nobodyさん
03/07/28 21:53ID:???まずフローチャートを書け。
それ以降は大学で聞け。
0187nobodyさん
03/07/28 22:03ID:???sleep(1);
print "ぽん\n";
0188あぼーん
NGNG0189nobodyさん
03/07/28 22:10ID:TipKdKzdランダムに3つの中から選ぶプログラムを作って
自分で入力した文字と比較。
結果を出力。でいいんじゃない?
0190あぼーん
NGNG0191nobodyさん
03/07/28 22:25ID:???print "じゃんけん(1=ぐー、2=ぱー、3=ちょき)\n";
<>;chop;
$a = int rand(3)+1;
$hoge = (($a == 1 && $_ == 2) || ($a == 2 && $_ == 3) || ($a == 3 && $_ == 1)) ? '勝ち' : '負け';
print $hoge,"\n";
# お粗末
0192nobodyさん
03/07/28 22:47ID:???0193nobodyさん
03/07/28 22:53ID:???<>;
print ('勝ち', '負け')[int rand 2];
0194nobodyさん
03/07/28 23:08ID:???/⌒ヽ
/ ´_ゝ`)時間的に、ここ笑わないといけないので、笑いますよ・・・
| /
| /| |
// | |
U .U
0195183
03/07/28 23:46ID:xYLAJnZKみなさんいろいろ案出していただいてありがとうございます。
結局自分の力不足で課題内容変えちゃいましたけど。
(みなさんの案は今後参考にさせてもらいます)
>192
今日始めてここに来たんですけど
まぁ課題が出るたびにここで聞くのと同じような根性の持ち主です。
とにかく…評価はCにケテーイぽ(つД`)
0196あぼーん
NGNG0198nobodyさん
03/07/28 23:56ID:???0199あぼーん
NGNG0200183
03/07/29 00:01ID:BcdoPCM8いやしてないし。むしろじゃんけんにしなかったし。
ウザイのでそろそろ逝きます。
0201nobodyさん
03/07/29 00:03ID:???自分の期待する答えがなかったからしなかった(というかできなかった)だけで。
0202nobodyさん
03/07/29 00:25ID:???試したらわかる程度に軽いやつで
0203nobodyさん
03/07/29 01:49ID:???0204168
03/07/29 07:41ID:???ありがとうございました。
Content Negotiationというのがあるとは全く知らず、そのまま表示できたのでびっくりです。
板違いでしたね(汗)
全部圧縮して、リンク先のアドレス変えるだけで問題はすべて解決しました。
大変感謝しております。
0205nobodyさん
03/07/29 08:56ID:pmxt/hz7cgiの中でlocaltimeで、6:00と7:00で処理を分けているんですけど、
crontabの時計とlocaltimeの時計は完全に一致しているんでしょうか?
スクリプトの中で6:00丁度だったらA、7:00丁度だったらBとやっても
crontabが起動した時間が5:58とかだったらAの処理が行われないと思うんです。
0206nobodyさん
03/07/29 10:14ID:???perldoc を調べなさい。
それから
man crontab。
0207nobodyさん
03/07/29 10:15ID:???crontabはcrontableのことだ。
要するにcronの設定ファイル(といっていいかどうかわからんが)
man cron
をすべき。
0208nobodyさん
03/07/29 10:21ID:???■ このスレッドは過去ログ倉庫に格納されています