このブログを検索

2013/02/28

mecabで名詞を数える

トレンドとなっている語を探したくて、mecabを使って名詞を数えるスクリプトを書いた。

単に名詞だけを数えると、「山田太郎」を「山田」と「太郎」を別々に数えてしまう。

mecabに「山田太郎」で辞書登録すれば一語にできるがそれもめんどくさい。

そこで、「姓と名が連続して登場したらひとつの名詞とみなす」という風にしたのだが、どうもスッキリ書けず、下記のようになってしまった。

一応これで用は足せているのだが、もっと簡単にかけないかなあ・・・



foreach (@array){
    for (my $n = $m->parseToNode ($_); $n ; $n = $n->{next}) {
        my $surf=decode('utf8',$n->{surface});
        my $feature=decode('utf8',$n->{feature});
        my @features = split(/,/, $feature);

        if($features[0]=~ /名詞/) {
            if($features[3] eq "名"){
                if($saveword){ $surf = $saveword.$surf };
                    &check_word_hash($surf,\%hash);
                    $saveword = undef;
                }elsif($features[3] eq "姓") {
                    if($saveword){
                        &check_word_hash($saveword,\%hash);
                    }
                    $saveword = $surf;
                }else{
                    &check_word_hash($surf,\%hash);
                }
         }elsif($saveword){
             &check_word_hash($saveword,\%hash);
             $saveword = undef;
         }else{
             if($saveword){
                 &check_word_hash($saveword,\%hash);
                 $saveword = undef;
             }
         }
     }
}



sedによる一括置換

cgiでrequireしているファイル名を mylib.pl から util.plに変えた。

sedで全部置換する。

sed -i s/mylib/util/ *.cgi


-i をつけるとファイルを直接書き換える。

2013/02/27

viのtips

カッコにカーソルを置いて % で対応カッコに移動

:!でコマンド実行

hashの値の降順でソート





foreach my $name (sort { $hash{$b} <=> $hash{$a} } keys %hash){
print "$name,$hash{$name}\n";
}

「数えてハッシュに登録し件数が多い順に表示」というのを最近おぼえてよく使うようになったのだが、


ハッシュの値でのソート方法をいつも検索して某所からコピーしていたのだがメンドクサイのでここに書いておく。





tweetを大量に削除

わけあって、自分の過去のtweetを大量にしかし全部ではなく削除する必要があった。

1個ずつWEBで削除していきながら、「これはAPIを使ってやるべきだな・・・」と思ったものの、やり方がわからず結局全部「手動で」消した。

調べたらごく簡単だったのでメモしておく。

tweetを削除するにはそのidを知る必要がある。まずはそれを知る方法。


#!/usr/bin/perl
use strict;
use warnings;
use YAML::Tiny;
use Net::Twitter::Lite;
use Encode;

my $config = ( YAML::Tiny->read('/hoge/config.yml') )->[0];
my $twit = Net::Twitter::Lite->new(
legacy_lists_api => 0,
consumer_key => $config->{'cs_key'}, consumer_secret => $config->{'cs_secret'} );

$twit->access_token( $config->{'ac_token'} );
$twit->access_token_secret( $config->{'ac_secret'} );


eval {
my $statuses = $twit->friends_timeline({ since_id => 1000, count => 10 });
for my $status ( @$statuses ) {
print encode('utf8',"$status->{created_at} <$status->{user}{screen_name}> $status->{text} $status->{id}\n");
}
};
warn "$@\n" if $@;


これは、Net::Twitter::Liteの、cpanのページの最初のサンプルほとんどそのままである。

tweet(status) は日本語なのでencodeしている。encodeしなくても表示できるが警告がうるさいのでencodeした。

use warning をはずせばいいのか・・・まあいいや。

since_id というのは名前からして、表示する最小のidであろう。ちなみにゼロにしたらエラーになった(省略できる)。

$status->{id}が、tweet(status)のidである。これはおそらく全tweetでユニークなidだ。

statusは新しいものからcountの数だけ取得される。

idがわかったら、以下のようにidを指定して destroy_statusを実行する。


eval {
my $statuses = $twit->destroy_status(3047606842882xxxxx);
};
warn "$@\n" if $@;


eval, warnとかの書き方はよくわからないがサンプルのままである。

あとは、tweetとidを表示し、消したいidを選んでdestroyすればよい。

「一括削除アプリ」みたいなものもあったのだが、遅い上に削除もできなかった。

注意すべきなのはあまり大量にいっぺんに表示・削除するとAPIの利用制限に引っかかるおそれがあることだ。

destroy_statusはAPIを1回呼び出すごとに1個ずつ消すから多分すぐアウトになるんじゃないか?

上記のやり方では1個だけ消せることを確認した。

大量に削除する際は要注意だ。




2013/02/25

RSSフィードを出力するcgi

ずっと前にやったRSSフィードを出力するcgiを見直す。

Jcodeを使っているが、古いのでやめる。

が、どうやって使うのかを忘れた。

ブラウザで実行するとxmlのソースが表示される。

これでいいんだっけ?

最近はRSSはあまり使わないけど、一応できるようにはしておきたい。

さて、やってみたら何の問題もなくrssが書けた。

多分、以前苦労したのは日本語のエンコードが良くわかっていなかったからだと思う。

rssフィードを出力するcgiを書いて、実行すると、ブラウザでxmlのソースが表示される。

そのurlをgoogleリーダーに登録する。フィードが表示される。

cgiを書き直して、フィードを更新してみる。googleリーダーを更新する。フィードが更新されない。

更新間隔が短すぎるからだろうと思って、いったんフィードの登録を削除し再登録すると新しいフィードが表示される。

さて、これをどうやって使うのだろうか?

たとえばブログの新しい記事を書いてそれを通知するときには、rssフィードを追加していくのか?

今日記事を書いて、フィードを出力する。翌日書いてまたフィードを出力する。この時に昨日のフィードを上書きしたら、

昨日のフィードを読まなかった人は読めなくなる。

だが、googleリーダーに登録してずっと読んでいなくても、後でまとめて読むことができる・・・

フィードを追加していくとすると、今度はずっとたまってしまう・・・




2013/02/23

logwatchを停める

logwatchは有益な情報が少ないので停めることにした。

どうやってインストールしたかもよく覚えていないが、

googleで検索し、/etc/cron.dailyにあるスクリプトを消す。

cron.dailyなるディレクトリの存在を初めて知る。

cron.hourlyなどもある。

それらの中のスクリプトを置いたおぼえはない。

毎日実行するようなものはここへ置くべきなのか。

たとえば /etc/cron.daily には logrotate というスクリプトがある。

毎日動くのはいいとして、何時に動くんだろう?午前零時?

話は変わるが、teratermでどこかに接続しているときに、途中でウィンドウのサイズを変えると切れる。

これはバグだね。

今再現できなかったのだがすぐつながってしまうからだ。

時々時間がかかることがあって、その時に起こる。