Perlコーディング初心者質問スレ Part 59
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2009/02/16(月) 11:42:29ID:gvPTpodw【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >2 以降
前スレ http://pc11.2ch.net/test/read.cgi/php/1218030872/
0596nobodyさん
2009/06/07(日) 23:23:24ID:???Test とか Class とかが知りたいです。
0597594
2009/06/07(日) 23:53:56ID:???その方法でうまくいきました。
ありがとうございました。
いろいろな形を試してみて、
( 'foo', [$a],[$b] )の形で動いたので
とりあえずこの方法でやっていこうかと思っていました。
0598nobodyさん
2009/06/08(月) 00:08:41ID:???そのまんま、cpanをby-moduleで見るのじゃあかんの?
ttp://www.cpan.org/modules/by-module/
それともこういう話?
ttp://d.hatena.ne.jp/yappo/20081010/1223630386
0599nobodyさん
2009/06/08(月) 00:39:27ID:???cpan.orgの方のページで解決しました。そんな便利なところがあると知りませんでしたorz
ありがとうございました。
0600nobodyさん
2009/06/08(月) 20:56:10ID:???例えば以下のようなハッシュの配列をソートしたいのですが、
my @member = (
{ 'name' => 'SUZUKI', 'point' => 80, 'pref' => 'TOKYO', 'flag' => '1'},
{ 'name' => 'TANAKA', 'point' => 100, 'pref' => 'OSAKA', 'flag' => '1' },
{ 'name' => 'SATOH', 'point' => 100, 'pref' => 'TOKYO', 'flag' => '0' },
);
1.ハッシュの'name'の値の昇順で配列をソートするにはどうすればよいでしょうか?
2.ハッシュの'flag'の昇順・'pref'の昇順で配列をソートするにはどうすればよいでしょうか?
3.ハッシュの'pref'の昇順・'point'の降順で配列をソートするにはどうすればよいでしょうか?
よろしくお願いします。
0601nobodyさん
2009/06/08(月) 21:13:22ID:???@member= sort{$a->{flag}<=>$b->{flag} || $a->{pref}cmp$b->{pref}}@member;
@member= sort{$a->{pref}cmp$b->{pref} || $b->{point}<=>$a->{point}}@member;
簡単な宿題だな
0603nobodyさん
2009/06/10(水) 20:00:53ID:???なぜかPerlのオートフラッシュが有効にならなくなってしまいました。
Debianをetchからlennyに変更したのでバージョン関係の
問題のような気もするのですが解決策が見つかりません…
何かご存じの方がいたら教えてください。
環境は下記のような感じです。
Debian/lenny Apache/2.2.9 mod_perl/2.0.4 Perl/v5.10.0
よろしくお願いします。
0604nobodyさん
2009/06/11(木) 04:02:08ID:???アップロードできる形式はgif、png、jpegで、
アップロードすると(ユーザーID).gifのような名前になります。
アイコンを更新する場合、アップロード前に
古いアイコンを削除する必要があるので、以下のように書きました。
opendir DIR, "./icon" || die("directory open error");
my @icons = readdir DIR;
@icons = grep $_ =~ /$id/, @icons;
closedir DIR || die("directory close error");
foreach my $icon (@icons) {
unlink "./icon/" . $icon;
}
ところが、これを実行したところ、プログラムがそこで止まってしまいます。
エラー等は吐かずにただ止まってしまうので、原因が分かりません。
$idとマッチするファイル名を@iconsに集めるまでは上手くいっているようなので
foreach以降に問題があるようですが、解決策がどうしても見つかりません。
どこに問題があるかご存知の方がいましたら、ご教示ください。
よろしくお願いします。
0605nobodyさん
2009/06/11(木) 08:20:11ID:???opendir DIR, "./icon" || die("directory open error");
while (my $icon = readdir DIR) {
unlink "./icon/" . $icon or die $! if /^$id\.(?:gif|png|jpe?g$)/i;
}
closedir DIR || die("directory close error");
ユーザー増えると遅くなるからディレクトリなめるやり方は良くないよ
0606nobodyさん
2009/06/11(木) 09:00:08ID:???メモリ使用量の問題はあるが。
opendir DIR, "./icon" || die("directory open error"); これと
opendir(DIR, "./icon" || die("directory open error")); これは
等価なので、括弧使って優先順位を変えるか、優先順位の低いorを使う。
あと、複数ファイルをまとめて消した方がサーバに優しいと思われ。
0607nobodyさん
2009/06/11(木) 10:11:35ID:???closedirに失敗してエラーで止まっているに100カノッサ。
実行時のカレントディレクトリの位置が期待したところと違うか
パーミッション関係かどっちかあたりかな。
0608nobodyさん
2009/06/11(木) 11:59:18ID:???書き直してて気が付いたことを。
ID の割り当てがどうなってるかわかりませんが、例えば ID が 60 って人がファイルをアップしたとしますよね?
600 の人も 6000 の人も 160 の人もファイルが上書きされたり、消されたりするので、そのマッチの仕方はやめた方がいいです。
またユーザーアイコンが1つしか無さそうなので、-e でファイルの有無を確認してから作業したほうがいいかと思います。
0610nobodyさん
2009/06/11(木) 12:17:45ID:???0612nobodyさん
2009/06/11(木) 12:19:39ID:???my $newicon; # ここに既に新しいファイルデータが入ってるとする
my $newfext; # 新しいファイルの拡張子
my $userid = 60;
# ファイル検索
my $userfname = '';
foreach (@fext){ $userfname = "./icon/$userid.$_" if -e "./icon/$userid.$_" }
# 仮出力
if(open(OUTFH, '>', "./tmp/$userfname.tmp")){
binmode OUFH;
print OUTFH $newicon;
close(OUTFH);
# 移動
move("./tmp/$userfname.tmp", "$userid.$newfext");
}
こんな感じか
0613nobodyさん
2009/06/11(木) 13:07:23ID:???その名前を $userid / 100 とかにするのも、運用回避としてはアリか。
0614nobodyさん
2009/06/11(木) 13:36:13ID:???my $complete = unlink(map{ "./icon/$id.$_" } qw(gif png jpg jpeg));
こんなでもいけるだろうけど。
0615604
2009/06/11(木) 14:30:45ID:???>>606さんのご指摘を受け、上記部分以外も含め open および close まわりは
すべて or に修正いたしました。
また、IDですが、アルファベット3文字+数字5文字の固定長にしており
ID発行時に重複もチェックしておりますので、
>>608さんのご指摘のようなIDマッチの重複はありません。
それでもまだ止まるので、もう少し止まる箇所を絞り込んでみたのですが、
どうもunlinkで止まっているようです。
unlinkで止まる原因にはどういったものが考えられますでしょうか。
0616nobodyさん
2009/06/11(木) 15:49:34ID:???0617nobodyさん
2009/06/11(木) 15:50:59ID:???「そんなにユーザー居ないし」でスクリプト組むのはやめたほうがいいですよ
0618nobodyさん
2009/06/11(木) 16:21:44ID:???だけにして実行するとかrm $fileでコマンドラインから
は消えるのかとかして原因の切り分けしろよ。
止まるなんて抽象的な表現じゃ分かんないだろ
0619nobodyさん
2009/06/11(木) 17:33:08ID:???読み込んだファイルの'key'という文字が出てくる次の行から
アウトプットさせたいんだが、うまくいかないです。
$flag = 0;
while($line = <IN1>){
chomp $line;
if($line =~ m/^key/){
$flag = 1;
print OUT1 $flag;
}
}
while($line){
if($flag == 1){
print OUT1 "$line\n";
}
}
みたいな感じで書いてみたんですが
if($line =~ m/key/)が認めらんねぇ、みたいなこと言われました。
どうしたらうまくいくか、教えてください。
0620nobodyさん
2009/06/11(木) 17:50:32ID:???0621nobodyさん
2009/06/11(木) 17:56:42ID:???while(my $line = <IN1>){
print OUT1 $line if $flag;
$flag = 1 if $line =~ /key/;
}
試してないけど、これでおk
0622nobodyさん
2009/06/11(木) 18:05:02ID:???行の終わりに全角スペースが入ってたから、それが原因だと思う。
全角スペースを可視化できるエディタを使うといいよ。
0624619
2009/06/11(木) 18:16:41ID:???皆、ありがとうございます。
>>621さんのプログラムで早速やってみたところ、なぜか
print OUT1 $line if $flag;
の行におかしなものがあるぜ、と言われて、動いてくれませんでした。
考えられる原因としては、何があるでしょうか?
unlinkがうまく動かなかったので、、、
unlink $file;
で済ませられるところを、、、
unlink $file unless -f $file;
と描いた記憶が蘇りました。
OS由来の変な誤動作とかかもしれないですね。
あと、単純にdiskがあやうすかも。
smartmontools等で確認するのも良いかも。
0628nobodyさん
2009/06/11(木) 20:10:41ID:???unlinkは、inodeの削除でつよ
> unlink $file unless -f $file;
ファイルが無いならunlinkって・・・
0629nobodyさん
2009/06/11(木) 20:23:23ID:???unlink $file if -e $file;
って書きたかったわけじゃなくて?
0631nobodyさん
2009/06/11(木) 21:56:39ID:???ネットワークドライブだったり不良セクタが発生してたりという事が多い。
0632604
2009/06/12(金) 02:45:55ID:???抽象的とのことですが、実際、CGIにフォームを送信するとそこから進まなくなってしまい
ブラウザを閉じるまで画面遷移も一切無く、エラー画面もログも表示されないという
文字通り「止まる」としか表現しようがない状態だったのです。
切り分け不足だったのはひとえに自分の力不足です。
その後、unlink $file or die $!;に記述を修正して実行したところ
以下のようなログが表示されました。
[error] [client ::1] Operation not permitted at huga line 122., referer: hoge
122行目はやはりunlink $file or die $!;です。
Operation not permittedを調べてみましたが、実行権に関するエラーのようですね。
もう少し実行権まわりを検証してみて、まだ動かないようでしたら
またお知恵を借りにくるかもしれません。勉強になりました。ありがとうございます。
0634nobodyさん
2009/06/12(金) 08:22:59ID:???unlink "./icon/" . $icon or die $!
って書いてあるじゃん。力不足とかいう話じゃなくて姿勢の問題。
他にもいっぱいアドバイス貰ってるのに相手に失礼だろ。
0635nobodyさん
2009/06/12(金) 11:12:28ID:???作成日時を変更することは出来ますか?
0636nobodyさん
2009/06/12(金) 11:19:41ID:???i領域書き換えないといけないわけだし
0637nobodyさん
2009/06/12(金) 11:38:04ID:???タイムスタンプ変更ソフトだと一括変更が多くて、
拡張子で分けたり条件で時刻だけ変更したり出来ないので
Perlでやりたいと思ったのですが残念です。
0638nobodyさん
2009/06/12(金) 11:43:59ID:???0639nobodyさん
2009/06/12(金) 13:20:19ID:???http://search.cpan.org/~wyant/Win32API-File-Time-0.006/lib/Win32API/File/Time.pm
0640604
2009/06/12(金) 14:18:45ID:???ごめんなさい。
>>605さんの発言を見て、
初めてunlink "./icon/" . $icon or die $!を試すことに気づきました。
それでやってみて初めてエラーログに表示されたので、
他の方のアドバイスもすべて見て参考にしつつ
自力でもなんとかしないと逆に失礼だと思って>>632のように書いたのです。
書き方等、不快にさせてしまって本当に申し訳ないです。ごめんなさい。
0641nobodyさん
2009/06/12(金) 16:46:11ID:???Windowsなので、>>639さんのリンクで解決しました!
ありがとうございました。
0642nobodyさん
2009/06/16(火) 12:04:02ID:???『2009.6.15.火』という文字列を
『2009/6/15-火』という状態に置き換えしたいです。
$hoge=~ s/./\//g で置き換え、
『2009/6/15/火』にしたあと一番最後の/を-に置き換えする事を考えていますが、
似たような処理が複数あるため、もっとシンプルに
『2009/6/15-火』に置き換えする方法をご教授頂ければ幸いです。
0644nobodyさん
2009/06/16(火) 12:29:59ID:???これでいいんじゃね
0645nobodyさん
2009/06/16(火) 12:36:28ID:???0646nobodyさん
2009/06/16(火) 12:42:00ID:???s/.(.*?).(.*?)./\/$1\/$2-/
0648nobodyさん
2009/06/16(火) 12:59:39ID:???じゃあこれでいいや
$hoge =~ s|『(.+).(.+).(.+).(.{1})』|『$1/$2/$3-$4』|;
あと、なんでみんな無理して/使うんだろ
0649nobodyさん
2009/06/16(火) 13:05:01ID:???これが妙に気になる
あとエスケープが面倒なときは {}!|# 辺りを見かけることのほうが多いよ
0650nobodyさん
2009/06/16(火) 13:14:08ID:???また聞き返されてそれの説明しなきゃいけないし
0652nobodyさん
2009/06/16(火) 14:34:08ID:???$str =~ s{(\d\d\d\d).(\d\d?).(\d\d?).(.)}{$1/$2/$3-$4}g;
>>644>>648さんに近いな。
0653nobodyさん
2009/06/16(火) 16:23:50ID:???$str = sprintf '%s/%s/%s-%s', split '.', $str;
これでいいだろ
汎用性も十分
0655nobodyさん
2009/06/16(火) 17:40:25ID:???0656nobodyさん
2009/06/16(火) 17:49:48ID:???0658nobodyさん
2009/06/16(火) 17:58:20ID:???特に今回なんかはセパレータが全角ピリオドだし見分けつかんよ
正規表現書くにしても二度手間とか思わず読みやすくして欲しい
0659nobodyさん
2009/06/16(火) 19:40:53ID:???0660nobodyさん
2009/06/16(火) 19:54:36ID:???処理の内容そのものを示すコメントって
あんまり良いコメントとは言えないのかもしれないけど。
0662660
2009/06/16(火) 23:17:31ID:???え? 何が?
0663nobodyさん
2009/06/16(火) 23:19:47ID:???人間を機械に近づける代わりにエッセンスで書ける
0665nobodyさん
2009/06/16(火) 23:53:35ID:???ぼく質問する側だもん
0666nobodyさん
2009/06/17(水) 00:46:18ID:???ハッシュのリファレンスかを知る上手い方法はありますでしょうか?
今考えているのはsprintfでリファレンスを書き出してみて
その文字列の中にHASH かARRAYのどちらがあるかでやろうかと考えています。
他におすすめの方法があればお願いします。
0668nobodyさん
2009/06/17(水) 00:54:57ID:???0669666
2009/06/17(水) 01:08:36ID:???ありがとうございます。
refの返り値がHASHかARRAYになってるんですね。。
リファレンスかどうかの真偽のみに使っていたので気がつきませんでした。
助かりました。
0670nobodyさん
2009/06/17(水) 01:55:06ID:???0671nobodyさん
2009/06/17(水) 18:23:12ID:???読み込んだデータ($sample)が120行ほどあって、
各行の先頭全てに’1−1’という文字列を放り込みたいんですが
全くプログラムが書けません。
どうか、教えてください。
0672nobodyさん
2009/06/17(水) 18:33:52ID:???0674nobodyさん
2009/06/17(水) 19:32:47ID:???0675nobodyさん
2009/06/17(水) 19:39:35ID:???0676nobodyさん
2009/06/17(水) 19:41:06ID:???0677671
2009/06/17(水) 19:54:39ID:???みなさん、ありがとうございます。
ばっちりできました。
が、初心者なんで皆さんのプログラムで
なぜちゃんと走ったのかが理解できてないので
出直してきますorz
0678nobodyさん
2009/06/18(木) 00:48:48ID:???0679nobodyさん
2009/06/18(木) 15:26:50ID:???@list = map(split(//, $_[0]), @csv);
@csv のすべての要素の最初の要素(文字列"am","au")を文字に分解したいのですがうまくいきません。
解決方法を教えてください。お願いします。
0681nobodyさん
2009/06/18(木) 18:06:39ID:???データの中にある特定の文字を消したいんですが、うまくいかないです。
while(<IN1>){
chomp;
@data = split(/-/, $_); #これは無視して下さい
@data2 = join(' ', @data);
という手続きで読み込んだデータをタブでつないで格納しましたが
都合上、全ての行に
red apple
red fire
てな感じで、タブで区切られずひとくくりにされてしまう箇所があります。
この中の"red "だけを全ての行から取り除いて残りをそのまま出力したいんですが
可能ですか?
初心者ながら置換をしてみようと
$data2 =~ s/Level1 //g
print OUT1 "$data2\n";
というプログラムを書いてみましたが、printできねーと返されましたorz
よろしくお願いします。
0682681
2009/06/18(木) 18:12:27ID:???下から4行目は
Level1 とか意味わからんのじゃなくて'red 'ですorz
0683nobodyさん
2009/06/18(木) 18:13:04ID:???0684681
2009/06/18(木) 18:29:39ID:???ホンマや!
と思って、;付け足してやってみたところ
今度はこのマッチングの表現がおかしいみたいなこと言われました。。
どこが間違ってるんでしょうか??
0686nobodyさん
2009/06/18(木) 18:35:41ID:???$str =~ s/ttp://www.*//;
みたいな感じに文字列に/使ってない?
0687nobodyさん
2009/06/18(木) 18:36:25ID:???該当行前後のソースも。
0688681
2009/06/18(木) 19:00:13ID:???redを空白に置換しようとしてるんで、文字列に使っちゃってることになるんですかね??
>>687
Use of uninitialized value in substitution (s///) at data_split line 15, <IN1> line 5788.
Use of uninitialized value in concatenation (.) or string at data_split line 16, <IN1> line 5788.
この2種類がガーっと出てきます。
ちなみにline15が$data2 =~ s/red //g;
line16がprint OUT1 "$data2\n";
です
0689nobodyさん
2009/06/18(木) 19:05:09ID:???0690nobodyさん
2009/06/18(木) 19:08:52ID:???そのエラーは$data2が未定義だと言っている。
681に書いてある付け加える前の元の部分には
@data2しか登場してないぞ。
0691nobodyさん
2009/06/18(木) 19:27:00ID:???redならそうはならないっす><
このエラー見る限り違う
つーかどういうフォーマットのデータをどういうフォーマットにしたいか教えてくれ
0692681
2009/06/18(木) 19:27:49ID:???そうだったんですか。。完全にわかってなかったです。
>>690
689さんが言うてるようにjoinが配列を返さないから
未定義だったんすね。。。
となると、、、
この"red "だけを消すにはどんな手が有効ですかね??
0693nobodyさん
2009/06/18(木) 19:39:03ID:???↓
どこかで設定したはず?→設定したはずの場所を正しく書き直す
↓
設定し忘れ?→設定すべき場所を考える
↓
わからない→とりあえず寝ちゃおう
0694nobodyさん
2009/06/18(木) 20:02:08ID:???strict
しておけ
0695nobodyさん
2009/06/18(木) 20:45:32ID:???ごめん言ってみただけ
0696681
2009/06/18(木) 20:59:17ID:???1 1 2 red fire 1232 0 [n]
みたいなのがざっと200行近くあって
この'red fire'がタブで区切れない、ひとくくりのデータになっちゃってます。
この中の'red'だけを一気にそぎ落とそうとしてる・・・って感じです
どうしたら良いですか??
■ このスレッドは過去ログ倉庫に格納されています