トップページ⇒php
1001コメント350KB

【Perl】初心者コーナー Part19

レス数が950を超えています。1000を超えると書き込みができなくなります。
0001nobodyさん03/01/11 13:52ID:???
初めに→「perl」その物のスレです。

1:自分はこう言う事がしたい。
2:それでこんな風にやってみたが・・・
3:それだとこんなエラーが出て上手く行かなかった。

1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。

あとは>>2-10にまかせた。
0896nobodyさん03/02/04 13:19ID:???
は!
なんとマヌケな…

ありがとうございました!
以後気をつけます。
0897nobodyさん03/02/04 14:28ID:???
おう、気をつけろよ
0898 ◆hMJAPH9PWA 03/02/04 14:31ID:???
最近妙にネタが多い気がする。
089971103/02/04 14:42ID:???
オンライン翻訳についてT電子に問い合わせたら、年50万とか言われた。
なんかもう自分で作りたくなっちゃったよ。PERLでcgi形式で翻訳スクリプト
なんて作ったら、どうなるんだろ。無謀か。
0900nobodyさん03/02/04 16:42ID:???
>>899
翻訳スクリプト作れるくらいの英語力(?)があったら翻訳スクリプトなんて必要ない。
0901nobodyさん03/02/04 17:02ID:???
>>899
1.入力フォームを作る
2.入力された文章をhttp://www.infoseek.co.jp/Honyaku?pg=honyaku_t_inout.html&svx=105420&svp=SEEK
にwgetで投げる
3.getしたhtmlから結果だけを抜き出して、整形して表示
0902nobodyさん03/02/04 17:31ID:???
CGI質問スレに間違えて書き込んでしまったので、以下コピペになりますが。

ファイルを、while (<IN>) {〜}といった記述をしないで、
一行ずつ読み込んでいく方法はないものでしょうか。

@file = <IN> といったメモリにファイル全部読み込む方法は使わず、
一行ずつ読み込んで、一行ごとに違う処理をしていきたいのです。

while の中でループ回数カウントしてifで判定しろ、なんていうのはなしで。

ファイルを一行読み込む場合、
open(IN,"$logfile");
$line = <IN>;
と、やれば出きるのはどこにでも書いてあるのですが、
2度目以降 $line = <IN> としても空でした…。

Perl は一行ごとに分けるデータ構造が身についてしまってるのがダメなのかなぁ…。
seek と read 使えばよさそうなのは解ってはいるのですが、
ベースから書き換えなくてはならず、このままの構造でなんとかできないものかと。
0903nobodyさん03/02/04 17:32ID:???
>>899
変に訳されるよりはむしろ原文のままのほうがいいな…
0904nobodyさん03/02/04 17:44ID:???
infoseekのテキスト翻訳ってGETで送るのか。
変なの。
0905nobodyさん03/02/04 17:45ID:???
>>902
んなこたーない。
これを実行してみればわかる。
#!/usr/bin/perl

use strict;

our $buffer;

$buffer = <DATA>;
print $buffer;
$buffer = <DATA>;
print $buffer;
$buffer = <DATA>;
print $buffer;

__DATA__
foo
bar
baz
090690203/02/04 18:00ID:???
ほんとだ、できてますね;
どこか初歩的なミスしてそうなので探してみます。
どうもでした。
090789403/02/04 18:35ID:???
>>895さんが教えてくれた通りにやったのですがまたエラーになってしまいました。
これは他の部分がやばいのでしょうか?
0908nobodyさん03/02/04 18:49ID:???
>>907
エラーの内容を書けってば。
0909nobodyさん03/02/04 20:00ID:ifLjuw1e
gzip展開したいんですど、

open F,"/bin/gzip -d temp.txt.gz |";

できません。
どうすれば良いでしょうか。
091090903/02/04 20:12ID:???
あースマソ、できてたわ。
出力先間違ってた。
失礼しました〜
0911nobodyさん03/02/04 20:54ID:???
>>902
>ファイルを、while (<IN>) {〜}といった記述をしないで、
>一行ずつ読み込んでいく方法はないものでしょうか。

意味不明
while (<IN>) は while($_ = <IN>)と同じ
要するに一行ずつ読み込んでいる。

>Perl は一行ごとに分けるデータ構造が身についてしまってるのがダメなのかなぁ…。
身についてないと思うよ。
091271103/02/04 21:43ID:???
>>900
>翻訳スクリプト作れるくらいの英語力(?)があったら翻訳スクリプトなんて必要ない。

英語に関しては、私自身は翻訳の必要などありません。掲示板に組み込んで
多言語翻訳掲示板を作れないか、ということです。

>>901
infoseek翻訳はそういう形で利用しても大丈夫なのでしょうか?

完全にフリーのものは、殆ど日本語翻訳まではまだサポートしていないし。
http://linguaphile.sourceforge.net/
0913nobodyさん03/02/04 21:48ID:???
>>912
恐ろしく電波な掲示板になること請け合いだな。
0914nobodyさん03/02/04 22:17ID:???
>>912
infoseekはネタでしょ。では、数ヶ月ならバレナイト思われ。
091571103/02/04 22:37ID:???
捕らぬ狸のじゃないですけど、翻訳掲示板が変に繁盛し出したら
いずれはバレてしまうんでしょうね。

上のLingaphileのように、フリーの翻訳ソフトは色々
開発されてはいるようですが。
GPLTrans http://www.translator.cx/
(こっちはCとPHP?)
091689403/02/05 07:12ID:???
>>908
エラーの内容といいますと?
インターネットサーバーエラーって画面以外にもエラーってあるんですか?

一応&jcode'convert(*{$TEST{$key}}, "euc");
こんな感じにしたらエラーはでなくなりました。
しかしeucにコンバートされてないみたいです。
普通にスカラーを作って日本語を入れて検索した場合は成功しますし、
上記のハッシュに英語をいれてもちゃんとなります。

原因のわかる方がいましたらお願いします。
0917nobodyさん03/02/05 10:39ID:???
>インターネットサーバーエラーって画面以外にもエラーってあるんですか?

自分のPCにPERLをインストールして、それを使ってテストする。
そうすればもっと詳しいエラーメッセージが見れる。
0918nobodyさん03/02/05 10:44ID:???
つぅかリモートサーバでCGIのテストしてんじゃねぇよボケと。
0919nobodyさん03/02/05 11:36ID:???
>>916
Internalすら読めないのに、よくPerlのコードを書けるねえ。
意外とエラーの実体はタイプミスだったりしてな。
とりあえずレンタル鯖でのCGIテストは今すぐやめろ。
0920nobodyさん03/02/05 11:47ID:???
初心者未満のプログラマはエラーメッセージに意味があることを知らない。
よって、彼には500 Internal Server Eroorで十分だったわけだ。要はエラーが起こったという事実が大切なのだから。



実行したらエラーが出ました。助けてください。


と言う質問がいかに多いか。
0921nobodyさん03/02/05 12:38ID:???
突っ込んでいい?

Eroor
0922nobodyさん03/02/05 12:53ID:???
(゚д゚)エロォア!!
0923nobodyさん03/02/05 13:28ID:???
(゚д゚)エルゥア!!
092489403/02/05 14:37ID:???
internalでしたか。すいません。

レンタル鯖でのテストはしてませんが?
activeprelとapacheを入れてIEのアドレスにPCのアドレスを入れてやってます。
0925nobodyさん03/02/05 14:44ID:???
activeperlにapacheと入れておいて、何故エラーを500しか認識できてないのか…
百年早い。せめてperlのデバッグ方を学んで出直してこいや。
ttp://www.harukaze.net/~mishima/perl/index.html
ttp://www.harukaze.net/~mishima/perl/cgi-debug-env/deb-tech.html
この辺りな。
092689503/02/05 14:53ID:???
他の連中に怒られそうだがまぁ…
use strict;
require 'jcode.pl';

my %TEST = ('A' =>'あ', 'B' => 'い');
my $key;
foreach $key(keys %TEST){
jcode'convert(\$TEST{$key}, "euc");
}

これで動くだろ。
092789403/02/05 16:22ID:???
ありがとうございます。
895さん、925さん、その他の方にも迷惑をおかけしました。
もう少し基礎を覚え直します
0928nobodyさん03/02/05 16:52ID:???
>百年早い。
100年前にperlはない罠
0929nobodyさん03/02/05 19:58ID:???
> 100年前にperlはない罠
100年後にもPerlはない罠
0930nobodyさん03/02/05 22:39ID:???
>>926
少し直してみました。

use strict;
require 'jcode.pl';

my %TEST = ('A' => 'あ', 'B' => 'い');
foreach my $key (keys %TEST){
 jcode::convert(\$TEST{$key}, 'euc');
}

#メモリを節約:
while (my ($key, undef) = each %TEST) {
 jcode::convert(\$TEST{$key}, 'euc');
}

#他のやりかた
foreach my $value (@TEST{keys %TEST}) {
 jcode::convert(\$value, 'euc');
}
0931nobodyさん03/02/05 23:03ID:???
keyを使わないならvaluesで取り出せば良いのでは。
とか、テストコードに言うのは野暮か。
0932nobodyさん03/02/06 00:06ID:???
メモリを節約するには、どういったことに
気をつければ良いのでしょうか。
0933nobodyさん03/02/06 00:07ID:???
>>932
無駄にリストとかハッシュを多用しない。
リファレンスが使えるところはなるべくリファレンスを使う。

0934nobodyさん03/02/06 00:22ID:???
数列から先頭の文字だけ削除する
スマートな方法はないでしょうか?

$last = @DATA;
@DATA = @DATA[1..$last]
0935nobodyさん03/02/06 00:31ID:???
@DATAのリストから先頭要素を削除したいなら
shift @DATA;
093693403/02/06 00:34ID:???
>>935
ありがとうございます。(_ _ )
0937nobodyさん03/02/06 01:02ID:???
>>931
3つ目で、valuesを使わない理由は、valuesで出てきたリストに対する
変更は、%TESTに反映されないから、です。

ってそういう意味じゃないか。
0938nobodyさん03/02/06 01:03ID:???
>>934
@DATA = @DATA[1..$#DATA];
の間違いだね。
093993403/02/06 01:46ID:???
>@DATA = @DATA[1..$#DATA];

$#DATAで、配列の最後の番号ということでしょうか?
これは応用が利きそうですね。
0940nobodyさん03/02/06 03:40ID:???
.
.
.
200212.txt
200301.txt
200302.txt
こういう年月の名前のファイルを作り出すプログラムで、そのテキストの中の数字を全部足していきたいので
open(IN,"200301.txt");
open(IN,"200302.txt");
こんな感じで一個一個開いて足しているのですが、
指定した月から現在の月までのファイルを開くような方法があれば教えてください
0941nobodyさん03/02/06 05:09ID:???
>>940
readdirでファイルリストを取得して
foreach等で回しつつ、
substrや正規表現で数字を切り出して、
if($xxx >= 200212)
などという条件つけてやれば?

または、予め何月以上というリストを作ってやって、
回しつつif (-e "$_.txt")で処理するか。
0942nobodyさん03/02/06 06:20ID:???
>>940
さらにこれからはもう一つ、
年月と数値だけ羅列したインデックスファイルを作っておくと便利だと思うよ。
 ・
 ・
200302<>5648
200303<>4421
0943nobodyさん03/02/06 12:30ID:???
>>942
そういうのはインデックスとは言わない
0944nobodyさん03/02/06 15:07ID:???
>>940
そのファイル名が「4桁年2桁月」になっているのであれば、、、
$start = "200201";
$end = "200301";

foreach ($start .. $end) {
open(IN,"$_.txt");
何らかの処理
}

でよいのでは?
0945nobodyさん03/02/06 15:29ID:???
>>944
阿保ッッ!
0946nobodyさん03/02/06 17:12ID:???
200213.txtが開けません。
094794203/02/06 17:30ID:???
>>943
あい。そうでした。。。
0948nobodyさん03/02/06 19:23ID:???
時間によって何か処理をしたい場合、
例えば任意日任意時の10〜20分の間に何か処理をするとして
($minは分)
if($min >= 10 and $min <= 19){⊂}
と
if($min =~ /1[\d]/){⊂}
とやるのはどっちが高速&負荷軽めですか?
つーかもっといい方法ありますでしょうか?
0949nobodyさん03/02/06 19:49ID:???
>>948
Benchmark;
じゃダメ?
0950nobodyさん03/02/06 19:52ID:???
文字切れちゃったけど
Benchmark.pm
use Benchmarkね。
0951nobodyさん03/02/06 19:55ID:???
>>940
my ($start, $end) = (200201, 200312);

my $cnt = $start;
while($cnt <= $end){

print $cnt, ".txt\n"; # なにかしら処理

my ($year, $month) = $cnt =~ /(\d\d\d\d)(\d\d)/;

$month++;
if ($month > 12){
$month = '01';
$year++;
}

$cnt = $year. $month;
}
単純に書いてみました。
0952別スレの優雅な94803/02/06 20:02ID:???
>>948
処理の重さだけなら後者が約2.2倍重いです。
前者を200万回処理するのにかかった時間0.69秒
後者を200万回処理するのにかかった時間1.51秒
実験は当方ローカル環境(CPU2.5GHz)

定期的に処理をしたいのであれば、UNIXコマンドのcronがありますが、
借りているサーバがshellを許可しているか、コントロールパネルにより
提供している必要がります。
0953郵政の歴史年表 03/02/06 21:24ID:iDPmTn07
perlを使って、
http://www.iptp.go.jp/museum/yusei/tsushin/nenpyou.html
にある1860年代から1990年代までの中から、
「郵便貯金の歴史」だけをgrep見たいに抜き出すこと出来ますか?

0954nobodyさん03/02/06 21:29ID:???
>>953
できるよ。

まず、そのサイトのデータを全部ダウンロードしてローカルに置きましょう。
(以下略)
0955nobodyさん03/02/06 21:30ID:???
ローカルに置いてからperlを使ってsystem("/bin/grep")てな感じ。














そうじゃないだろ・・・・
0956(=`ェ´=) ◆9rperl5mn2 03/02/06 21:31ID:???
>>953 作ればできるよん。
0957nobodyさん03/02/06 21:47ID:???
<tr>
<td valign=top nowrap><b>([^<]*)</b></td>
<td>

<tr>
<td valign=top><font color=(?:ff9cff|9cff31|0031ff)>●</font></td>
<td>([^<]*)</td>
</tr>
0958nobodyさん03/02/06 21:53ID:???
>>948
はっきりいってそんなのperlの起動コストやI/Oコストに比べればゴミみたいなもん
分かりやすい方選んどき
0959nobodyさん03/02/07 03:13ID:Md2X1ufV
POSTで受け取ったファイルの、
アップロードする前のオリジナルネームは
どこを参照すればわかるのでしょうか?
 環境変数 Perl 一覧
などとググっても見つけられませんでした。
よろしくご教示ください。
0960nobodyさん03/02/07 03:32ID:???
multipartでPOSTした場合はContent-dispositionヘッダ。
http://www.yo.rim.or.jp/~getsu/document/rfc1867j.txt

こういう意味じゃない?
0961nobodyさん03/02/07 03:55ID:???
>>960
なるほど。格納されている場所がわかりました。
実際の取得方法(スカラー変数への代入)を調べてみます。
ありがとうございました。
0962nobodyさん03/02/07 16:46ID:04vl2wLA
指定したディレクトリにあるファイルのファイル名を
全て配列に代入するにはどうすればいいんでしょうか?

例えば、cgi本体と同じ階層にある「log」というディレクトリに
0.dat,1.dat,2.datがある時に、
最終的に@dataに0.dat,1.dat,2.datが代入されている
という風にするにはどうするのでしょうか?
0963nobodyさん03/02/07 16:54ID:???
opendir
0964nobodyさん03/02/07 16:54ID:???
>>962
http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/pe_k03.htm
0965名無しさん@Meadow03/02/07 17:01ID:???
>>962
サブディレクトリもでしょ。.とか..とかのディレクトリは
入れないんでしょ。これでいいと思うよ。

#!/usr/local/bin/perl

# コマンドラインで指定したディレクトリの中にあるすべてのファイルを配列に入れる
$usage = 'perl files-in-dir.pl 絶対パス';
$starting_dir = shift;
die $usage if $starting_dir eq "";

sub search {
my($dir, $depth) = @_;
my $handle = "DIR$depth";
opendir($handle, $dir) or die $!;
while($file = readdir($handle)) {
next if $file =~ /^\.{1,2}$/;
if (-d "$dir/$file") {
&search("$dir/$file", $depth + 1);
} else {
push(@files, $file);
}
}
closedir($handle);
}

search("$starting_dir", 1);

for(@files) {
print;
}
096696203/02/07 17:40ID:???
解決しました。皆さんありがとうございました。
0967nobodyさん03/02/07 21:04ID:???
モジュール使えよ
0968nobodyさん03/02/07 21:06ID:???
>>967
はいはい。
0969nobodyさん03/02/08 00:03ID:???
Perl初心者さんへ、世の中PHPに移行する中、
なんでPerlを覚えてるの?
借りてるサーバがPerlしか使えないとかかな?
マジレスきぼん。
0970マジレス03/02/08 00:06ID:???
どんな世の中だっつの。おまえの頭の中のか?
0971nobodyさん03/02/08 00:23ID:???
>>970
初心者さん マジレスありがとう。  
0972nobodyさん03/02/08 00:24ID:???
>969
( ´,_ゝ`) プッ
0973しょしんしゃ03/02/08 00:26ID:qxZih98+
ファイル処理プロセスが面倒
日本語処理が面倒
ソケット通信が未熟
0974nobodyさん03/02/08 00:43ID:???
社員番号 社員名 身長   体重
$no     $name $heught $weight

とする場合、身長の降順、同じ場合は体重の昇順に
体重まで同じ場合は、さらに社員番号の昇順に
社員番号、社員名、身長、体重をprintしたい場合は
どうしたらよいでしょうか?(複数キー)
097594003/02/08 01:27ID:???
ありがとうございました
0976nobodyさん03/02/08 02:04ID:???
>>974
まずは色々とやってみる。
それでだめならぐぐる。

それくらいのことをしないと初心者とは認定されませぬぞ。
097797403/02/08 02:37ID:???
>>976
失礼しました。一応自分で書いてみてテストした結果、
下記のやり方で問題なかったのですが文法的におかしい
ところ、他に綺麗なやり方がありましたらご教授下さい。
(とくに下記の場合3つのキーとしているのに「keys %hei」
だけでもよろしいのでしょうか?)

open(FILE);
while (<FILE>) {
($no,$name,$height,$weight) = split(/<>/);
$nam{$no} = $name;
$hei{$no} = $height;
$wei{$no} = $weight;
}
close(FILE);

foreach $no (sort { ($hei{$b} <=> $hei{$a}) || $wei{$a} cmp $wei{$b} || $no{$a} cmp $no{$b} } keys %hei) {
print "$no $nam{$no} $hei{$no} $wei{$no}<BR>";
}
0978本7 ◆JMmE5ppk7Y 03/02/08 03:24ID:???
掲示板の名前表示にトリップ機能を追加しようとおもいます。
トリップ変換のアルゴリズムはその辺のトリップチェッカーを拾ったんで途中に割り込ませようとおもいます。
で、すでにできあがってる2chスクリプトなのですこし強引ですが名前をdatファイルに保存する際に

投稿の際に名前入力してそれをdatファイルに保存してるのがread.cgiだと決めつけて考えてます。
空の変数$karinameを用意してそこに正規の名前変数$nameを代入して料理しよかと思いました。

まず最初に良く分らないのが文字列変数$nameに"#"が入ってる時だけ"#"以降の文字列抜き出しをするに
はどいう形の分がいいんでしょうか?

さらに抜き出せたとしてそれを変換ルーチンで料理。もう一つ用意した$ryouriに代入

$name=$ryouri で元にかえしてやってその後は通常の流れに続くという方法でよいでしょうか?

雑な質問のしかたで申し訳ないです。よろしくお願いします


0979nobodyさん03/02/08 04:03ID:???
>>977
こんなデータを作ってみました。
33<>c<>169<>120
22<>b<>169<>68
1<>a<>169<>68
正しくはa,b,cさんの順ですよね?

>>978
正規表現でマッチング。
0980 03/02/08 04:12ID:???
>>978
こんな感じ?

$name =~ s/?#(.+)/&trip($1)/eg;
sub trip {
my ($conv) = @_;
my $conv = substr(crypt($conv, $salt), -8);
($conv);
}
0981同一人物?03/02/08 04:22ID:???
264 :本7 ◆HON7/awDa. [sage]:03/02/07 20:34
この早さでは言いにくいが













旧2ch式BBS立てたけど誰も来ない
0982nobodyさん03/02/08 08:23ID:???
>>977
> open(FILE);
本当に問題ないの?

--- test.dat ---
ABC-001<>foo<>165<>65
ABC-002<>bar<>170<>70
ABC-003<>baz<>170<>65
ABC-004<>boo<>170<>65
---

my $file = './test.dat';
open FILE, '<' . $file or die;
my(@item, @person) = qw(i n h w);
chomp, @{$person[$. - 1]}{@item} = split /<>/ while <FILE>;
close FILE;

print map "@{$_}{@item}<BR>\n",
sort {
$b->{'h'} <=> $a->{'h'} ||
$a->{'w'} <=> $b->{'w'} ||
$a->{'i'} cmp $b->{'i'}
} @person;

参考。
http://www.google.co.jp/search?q=Schwartzian+Transform&hl=ja&lr=lang_ja
0983nobodyさん 03/02/08 14:06ID:???
>>982
どうだ、凄いだろ、俺のチンチン!っていう回答
熟女は喜ぶが処女は痛がる
0984nobodyさん03/02/08 16:30ID:???
>>982
Perlらしいコードですな。
0985本7 ◆HON7/awDa. 03/02/08 19:05ID:???
>>980
アドバイスありがとうございます
抜き取った文字列はどこに代入されるのでしょうか?
どしろうとで申し訳ないです
0986nobodyさん03/02/08 23:03ID:???
>>985
勝手に置換されるように書いてあるぞう。わからなくてもとりあえず読んでみよう。
0987 03/02/08 23:04ID:???
backslashが文字化けた。
$name =~ s/¥#(.+)/&trip($1)/eg;
#の後の(.+)がトリップ用数字に相当。
(.+)が$1に入って、
これにsub tripで処理したものを、
元のやつと置換する。
$name = "私の名前 #123456";
が
$name = "私の名前 aKsdjA4w";
みたくなる。
0988nobodyさん03/02/08 23:15ID:r91Y0UUN
open F,"+<$file";
while(<F>){print;}
seek F,0,0;
print F $temp;
close F;

としたとき、$tempのサイズが元のファイルサイズより小さいと、
$fileの元のデータが後半残ったまま上書きされてしまいました。
これはやはり上書きモードで開き直さなければ駄目でしょうか。
0989nobodyさん03/02/08 23:23ID:???
>>988
わかんないけど、seek後truncateしてみたら?
0990nobodyさん03/02/08 23:28ID:???
>>989
うお、できました!サンクスです。
0991本7 ◆HON7/awDa. 03/02/08 23:30ID:???
>>986
なれこれいじいったらトリップ入ってないときはそのままで出力できるようになりました。
あとは◆を名前欄に入れたら◇になるよう改造してみます
0992nobodyさん03/02/08 23:43ID:???
例えば、
http://www.yahoo.co.jp/
のソースを $st バイトから $to バイトまでのみ
ネットワーク通信によって取得するにはどうすればいいですか?

LWPとかSocketとか頑張って調べましたがわかりません
よろしくお願いします。
0993nobodyさん03/02/08 23:45ID:???
>>992
もうちょっとSocketとHTTPの勉強すればいいよ。
0994nobodyさん03/02/08 23:54ID:???
perlのmyって変数を続けて書くと最初のやつ以外はmy変数じゃなくなってしまうんですか?

例:
my  $i;    # ←はmy変数
my  $i,$j,$k; # ←は$iだけがmy変数(残りはglobal?)
my  ($i,$j,$k);# ←は全てmy変数

↑このような認識でいいのですか?
0995nobodyさん03/02/08 23:58ID:???
myは関数じゃないからそうなるんだよーん。
レス数が950を超えています。1000を超えると書き込みができなくなります。