性格悪い人が優勝

再びお世話になります。
perl5.14の環境でログ表示のみのスクリプトを作っています。

4<>一平<>記事<>オヤ<><><>
3<>次郎<>記事<>おや<><><>
1<>太郎<>記事<><><><>
1<>次郎<>記事<><><><>
2<>花子<>記事<><><><>
2<>太郎<>記事<>親<><><>
1<>太郎<>記事<><><><>
1<>花子<>記事<><><><>
1<>太郎<>記事<>oya<><><>

上記のようなログデータから4番目の値がある行だけを取り出したいです。
以下のように書くと一行目のオヤの行だけが取り出されてしまいます。
html側で言うとレス記事の行を非表示にしたいのです。

# ログの表示
foreach $i (@file){
($num,$name,$msg,$oya,$url,$mail) = split(/<>/,$i);
@file = grep /$oya/, @file;
print <<EOM;
$num<br>
$name<br>
$msg<br>
$oya<br>
$url<br>
$mail<br>
---------------<br>
EOM
}

4番目の値の文字列が変ってしまう場合も一緒に取り出すにはどう書けばよいのでしょうか?
よろしくお願いいたします。

質問者からの補足コメント

  • すみません。
    foreach $i (@file){
    ($num,$name,$msg,$oya,$url,$mail) = split(/<>/,$i);
    ではなくて
    foreach (@file){
    ($num,$name,$msg,$oya,$url,$mail) = split(/<>/,@file[$i]);
    こうでした。

      補足日時:2015/12/16 05:46

A 回答 (7件)

正直にいわせてもらうと, 何をどう考えてどんなプログラムを作れば


「レスが3行以上続くと空白ページも出現します」
なんて器用なことができるのか想像もつかない.
    • good
    • 0
この回答へのお礼

色々試しましたがやはりうまく行きません。
最初からもう一度書き直してみます。
要領を得ない質問にも関わらず、お付き合いくださって有難うございました。

お礼日時:2015/12/18 00:31

それ, 質問文のどこにも書いてないことだよな.



それができたとしたら, 次はどんな新しい条件が生えてくるんだ?
    • good
    • 0
この回答へのお礼

お世話になっております。
「ループ中で変更しているので他の処理に影響が出そう」ってのは何を気にしている?
と聞かれたので書いたのですよ。
このような弊害が出る事がないように$oyaのある行のみを取り出す方法はないのでしょうか?
よろしくお願いいたします。

お礼日時:2015/12/16 21:26

ごめん, 言われるまで気づかなったけど「$i に『4番目の値』があったら表示しなかったら表示しない」は俺のミスだ. 本当は


「$i に『4番目の値』があったら表示し, なかったら表示しない」
と書きたかったんだろう, たぶん.

で正解はまさに
「ログ表示部分を
if ($oya ne "") {
}
でくくった」
だ.

ちなみに「ループ中で変更しているので他の処理に影響が出そう」ってのは何を気にしている? #3 では確かに
その中で @file を変更したらまずい
と書いたけど, (grep の行は完全に消しておいて) 上のようにログの表示部分をいじるだけなら @file は変更してないよ.
    • good
    • 0
この回答へのお礼

お世話になっております。
なるほどgrepを使わなければ大丈夫なのですね。

気にしているのは1ページごとの記事表示の切り替えでのことです。
データの量が多い場合のため実際のスクリプトでは1画面に表示する数を指定してフォームボタンで次の画面に飛ぶ処理をしています。
今回のif文でくくるとレス記事は非表示になりますが1画面の数でレス記事分も数えているようです。
1画面3記事を指定すると上のログファイの例では最初の画面で

4
一平
記事
オヤ
---------------
3
次郎
記事
おや
---------------

こう出て、次へのボタンを押すと

2
太郎
記事

---------------

となります。
これはレス記事の数も数えているって事ですよね。
つまりレスが3行以上続くと空白ページも出現します。
試行錯誤したのですが$oyaの数だけの数え方がどうにも解りません。
どのようにしたら良いのでしょうか?
またはif文以外で$oyaのみを取り出す方法はありますでしょうか?
よろしくお願いいたします。

お礼日時:2015/12/16 03:59

もう 1度確認するが


「$i に『4番目の値』があったら表示しなかったら表示しない」
というのはどう書くのかな?
    • good
    • 0
この回答へのお礼

お世話になっております。
色々試してループ中でログ表示部分を
if ($oya ne "") {
}
でくくったら望みの結果が出ましたが何か違う気がします。
これだと言われていたループ中で変更しているので他の処理に影響が出そうです。

「表示しなかったら表示しない」というのは意味が解りません。
私がそのようなおかしな処理をしているのに気付けという事でしょうか?
もちろん間違っているから動かないのですけど何が間違っているのか解っていません(涙)。
よろしくお願いいたします。

お礼日時:2015/12/15 06:35

まず,


foreach $i (@file)
とループを回しているのだから
その中で @file を変更したらまずい
というイメージは持たないといけない.

その上でだが, 「$i に『4番目の値』があったら表示しなかったら表示しない」というのはどのように書くかな?
    • good
    • 0
この回答へのお礼

foreach $i (@file)以前で処理しておくと言う事でしょうか?
なんとなくおぼろげにそんな気はしていました(汗)。
perlのバージョンが低かった頃は
@file=grep{split /<>/; $_[3]++} @file;
こんなコードをループ前に書くと望みどおりの結果になっていたんですけど5.14では滅茶苦茶な表示になりました。
これは自分では書き方を考えられないのでwebを検索すると「配列からユニークな要素だけを取り出す」というようなgrepを使う情報が沢山ありそれを参考にしていました。
@file=grep{split /<>/; $_[3] ne ""} @file;
これでも動いていたのですが5.14では何もしてくれません。
それで色々と試していたら何も取り出さなくなって、自分ではお手上げで恥ずかしながらこちらに質問しました。
1番目の要素が最後に出現する行だけの検索でも良いのかも知れないとも思うのですがそのような処理の仕方も解りません。
何卒お力をお貸しください。
よろしくお願いいたします。

お礼日時:2015/12/14 17:56

うぅん....



@file = grep /$oya/, @file;
の意味は理解できてるのか?

そもそも, なんで grep を使うんだ?
    • good
    • 0
この回答へのお礼

お世話になります。
実はよく解っていません。
4番目の要素がいつも同じ値ならこのコードで望んだ結果が得られたので使っていました。
どのようにすれば値が変っても検索に適用されるのでしょうか?
よろしくお願いいたします。

お礼日時:2015/12/14 01:08

「4番目の値がある行だけを取り出したい」ってどういうこと? その例だと, どういう結果が欲しいの?

    • good
    • 0
この回答へのお礼

お世話になります。

4
一平
記事
オヤ
---------------
3
次郎
記事
おや
---------------
2
太郎
記事

---------------
1
太郎
記事
oya
---------------

こういう結果が欲しいのです。
現状では最初に出現した$oyaの値だけにマッチしてそれ以下の行の値の違う行にはマッチしないようです。
ログファイの例で一行目の$oyaの値が以下の行にある場合はそれにもマッチするようです。
そもそもマッチしていないのか、マッチしているのに取り出し方が悪いのかもよく解っていません(汗)。
@file = grep /$oya/, @file;
よろしくお願いいたします。

お礼日時:2015/12/13 02:48

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!