2011年4月25日月曜日

perlでエラーログを抽出する

最近、仕事でデータをインポートする作業が多くなっています。
1000件、2000件ともなると、エラーが置きたさいにデータの確認が大変です。

エラーのデータだけを抽出したcsvを出力することで、どのようなデータでERRORが起きるのかの把握で時間短縮ができるのでは?と思い、Perlで実装しました。

インポートの際には、下のようなログがでます。
SUCCESS line no. 1 ...
ERROR line no. 2 ...

実装としては、
*csvファイルとログテキストを同じ階層に配置させておく。
*ログテキストを読んで、ERRORの後の番号(行数)を配列として保存する
*CSVファイルを読んで、上で保存した番号(行数)のデータだけを新規のCSVとして出力する



#!usr/bin/perl

use strict;
use warnings;

## register files
print "log_txt : ";
chomp(my $log_txt = <STDIN>);
print "csv : ";
chomp(my $csv = <STDIN>);
print "exporter_csv : ";
chomp(my $export_csv = <STDIN>);

## data of culumn for csv
my @error_num = ("0");

## run
my $error_data = &error_data_number();
my $create_csv = &create_csv_with_error_data();
print "compleate!\n";


## stored number of error data
sub error_data_number {
        open IN, '<', $log_txt or die "file open error: $!";

        while(<IN>) {
                chomp;
                if (/(ERROR line no. )(\d+)/) {
                        push(@error_num, $2);
                }
        }
        close IN;
}


## create csv with error data
sub create_csv_with_error_data {
        open IN, '<', $csv or die "$csv file open error: $!";
        open OUT, '>', $export_csv or die "$export_csv file open error: $!";

        my @data = <IN>;
        while (@error_num) {
                my $fred = shift(@error_num);
                print OUT $data[$fred];
        }

        close IN;
        close OUT;
}


ここ最近Perlを勉強中ですが、たいていのことはPerlで実装できるんだな、と感じてきました。
Linuxでは標準でインストールされていて、使い勝手の良い言語なだけに、インフラ屋は、Perlを理解して使いこなすことで、作業効率が上がります。

勉強もかねて、作業を効率にさせてくれるものは、どんどん実装していこうと思います。
とくに自動化できるところは、押し進めていきたいです!


2011年4月24日日曜日

六本木のバーを飲み歩き

金曜日の夜から日曜日の朝にかけて、六本木でひたすら飲み歩きました。
とても美味しいお酒に出会えて、言葉に言い表せれないほどの喜びでいっぱいです。

土風炉 http://www.hotpepper.jp/strJ000011554/
スタートはこのお店。
六本木駅すぐそばで、店内はとても広いです。
個室がそろっているし、値段もお手頃なので、わりと使っています。



Public BAR Abbot’s Choice http://r.gnavi.co.jp/a430400/
美味しいウイスキーが飲みたい。
値段はしますが、美味しいウイスキーが揃っています。
お酒が豊富で、騒がしくもなく、ウイスキーがどんどん進みました。



一蘭 http://r.tabelog.com/tokyo/A1307/A130701/13003482/
ここいらでおなかがすいてきた。
ちなみに深夜2時はまわっています。



??
店の名前を覚えていない・・・
わりと安くて美味しかったので、探します。


そして朝帰宅→睡眠→宅飲み→再び六本木へ


まずは、
NEWLEX http://www.newlex-edo.com/index2.html
六本木のクラブではまずまずの知名度ではないでしょうか。
今日は、ここで主催していたパーティに。
雰囲気だけ楽しみました。



BAR A-POINT  http://www.bar-a-point.com/menu.html
愉快な外国人が踊っていました。
二人組の女性がいたので、話かけると、18歳。
六本木にもこんな若い女性がいることにびっくりしました。



五色 http://beer-cuisine.com/wp/?page_id=2
ビールは種類が揃っていて、値段は高めだけど、酒よし雰囲気よしな店です。
今回の最も大きな収穫です。
大事な女性と行ってしかるべき場所でした。



BAR 1984 http://www.bar1984.com/?stop=true#top
今日は、良いバーを探しにきたのに、入ってみるとガールズバー。
マティーニが薄めだったのが、残念。
店員と楽しく話せたからOKかな。美人います。



BAR & LOUNGE http://www.freezeroppongi.com/
最後の締めです。
ビールが豊富でした。聞いたこともないビールがありました。
店長が面白い人ですっかりペースを持ってかれました。


怒濤の2日間でした。
お金もとぶわ、酔うわ、で大変でしたが、楽しかったです。
なにごとも経験です。

2011年4月12日火曜日

正規表現

Perlには、組み込まれている専用の特殊言語によって記述された小さなプログラムをもっています。これを正規表現といいます。正規表現 (regular expression) は、高速で柔軟で信頼性の高い文字列処理を行います。Perlでは、正規表現のことをしばしばパターンと呼びます。その結果はTrue(マッチする)か、False(マッチしない)のいずれかになります。

単純なマッチ
$_の内容に対して、正規表現をマッチさせるには、スラッシュで囲んで指定します。

$_ = "Taichi Shindo";
if (/aich/) {
print "It matched.\n";
}

/で囲まれた文字列を、$_の中から探し、見つかれば真の値を返します。



ワイルドカード文字
ドット( . )はワイルドカード文字です。改行文字を除いたあらゆる文字1個にマッチします。

例)/ab.cd/
        abbcd, ab=cd, ab.cd の全てにマッチします。


量指定子
パターンの中で何かを繰り返したいときにつかいます。
■アスタリスク(*)は直前に置かれたものに0回以上マッチすることを表します

■プラス記号(+)は直前に置かれたものに1回以上マッチすることを表します

■クエスチョン記号(?)は直前に置かれたものが0回もしくは1回現れるのどちらかです。
        例)/ab-?cd/
                ab-cd, abcd のいずれかを含む文字列にマッチする

■ブレース( { } )は、繰り返し回数の最小と最大を表す2つの数字をコンマで区切って並べる。
        例)/a{2, 4}/
                aa, aaa, aaaa のいずれかを含む文字列にマッチする


選択肢
縦棒( | )は、その左側か右側のどちらか一方にマッチすることを表します。
例)/abc | def | ghi/
        abc, def, ghi のどれかを含む文字列にマッチします


文字クラス
文字クラスは、ブラケット( [ ] )の間に文字を並べ、その文字のどれか1個にマッチする場合、Trueを返します。
例)/[abc]/
        a, b, c のどれかの文字のを含む文字列にマッチする

■ハイフン ( - ) を使って文字の範囲を指定する
ハイフン( - )を使って文字の範囲を指定することができます。
例)/[a-zA-Z]/
        アルファベットの大文字・小文字合わせて52文字のどれかに含む文字列にマッチする

■文字クラスのショートカット
よく使われる文字クラスについてはショートカットが用意されています。
\d        数字にマッチする [0-9] と同じ意味
\w        全ての文字 [a-zA-Z0-9_]と同じ意味
\s        空白文字 [ \f\t\n\r ] と同じ意味(フォームフィード、タブ、改行文字、復帰文字)


アンカー
正規表現では、文字列の特定の場所に固定するために、アンカーが用意されています。
■キャレットアンカー( ^ ): 文字列の先頭を表す
        例)/^abc/
                文字列の先頭にある abc を含む文字列にマッチする

■ドル記号アンカー( $ ): 文字列の末尾を表す
        例) /abc$/
                文字列の末尾にある abc を含む文字列にマッチする

*よく使われるパターンに空白文字にマッチを表す、/^\s*$/ があります

■ワードアンカー( \b ) : ワードの両側にマッチします
        例)/\babc\b/
                abc の文字列にマッチする       
                abcd, zabc などの文字列にはマッチしない


後方参照
カッコで囲むことによって、パターンを正規表現エンジンに記憶させることができます。これによって、後方参照を実現することができます。

例)/(.)\1/
        任意の1文字にマッチして、その後ろに同じ文字がもう1個続くものにマッチする
        abccd, abb などを含む文字列にマッチする

2011年4月11日月曜日

Oracle用語を書きなぐってみた

なかなか奥が深いOracle。
まだまだ知識は曖昧だけども、簡単にまとめてみました。

■データベースって何?
複数のアプリケーションやユーザによって、データが共有できるように整理された、データの集合体を言います。

データベースの種類としてはさまざまなものが存在します。
・階層型データベース
・リレーショナルデータベース
などなど


■Oracleはどんなデータベース?
RDBMS(リレーショナルデータベース管理システム)
つまり、リレーショナルデータベースを管理するソフトウェアのことです。
特徴として、データベース言語SQLが標準言語として用意されています。


■インスタンスって何?
Oracleインスタンスは、データベースを含む関連データの管理を行います。
1つのデータベースには、最低1つのインスタンスが関連付けられます。


■SID(システム識別子)
複数のインスタンス、データベースを作成した場合、指定したDBへの接続の手段はどうすればいいでしょうか。
Oracleのインスタンスおよびデータベースを識別する情報として、"SID (システム識別子)" が使われます。
DBサーバー上で、Oracleに接続する際、環境変数ORACLE_SIDを指定して使っています。


■システムグローバル領域
Oracleインスタンス内のメモリー群を、システムグローバル領域といいます。


■PGA
PGA (プログラムグローバルエリア) は、SQLを実行するサーバープロセスごとに割り当てるメモリ領域です。セッション情報やソート処理に使用されます。


■リスナー
Oracleリスナーは、Oracleデータベースへの受付窓口です。
リスナーはSQLなどの処理を受け取ると、サーバープロセスに処理を引き渡し、クライアント端末とサーバープロセス間で直接やり取りを行い、リスナーはその処理に関知しません

2011年4月7日木曜日

懐かしのファッションショー

ポストを見ると、1枚のDVDがありました。
半年前のファッションショーをおさめたDVDです。


懐かしいなー。昭和女子大の友達に誘われ、文化祭のファッションショー出たときのことです。


”デニム&デニムはダメですか?” をスローガンに立ち上がったOverのもと、みっちりデニムを着せられました。
帽子までデニムという徹底ぶり。
(僕は、デニムなんてものは家に一枚も・・・。)こそこそ言ってみる。


冷静に考えてみよう。
”あなたはデートに上下デニムで行けますか?”
”恋人がデートに上下デニムで現れたら、あなたはどうしますか?”

火を見るより明らかさ、とお馴染みの台詞が出てしまいそうです。


でもね、可愛かった
背が高くスタイルの良い女性には全身デニムでも似合うのかも。


と、半年前の思い出に浸りながら、DVDを再生してみました。


あー懐かしい。
ほとんど知らない人と一緒にショーをしたんだけども、すごく楽しかったんだよな。


%E3%83%95%E3%82%A1%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%BC-2011-04-7-22-54.png


スタッフへ
衣装もそうだけど、歩き方からポーズまで色々お世話になりました。
待機している間に、差し入れも持ってきてくれて、あんなにドーナッツを食べたのは生まれて初めてだ。
平凡な日々に刺激的なひとときを与えてくれてありがとう。


一緒にショーを盛り上げてくれたデニマーへ
本番と打ち合わせぐらいしか会っていないのに、いろんなことを話せて楽しかったです。
みんなの明るい性格ゆえに、すぐに打ち解けることができました。
ふと、また会いたくなってきたわ。



すごく緊張していたの覚えています。
日常生活とはかけ離れた場所に僕はいました。
ショーが終わっても、なかなか抜け出せないほどに。

ありがとう。
このような機会を恵んでくれた人に感謝します。

2011年4月6日水曜日

英会話レッスン

念願の英会話を初めました。

クラブやバーに行くと必ずと言っていいほど外国人と話をします。
英語を話せないとこういう場で堂々と振る舞えません。
美人な外国人を見ても、話しかけれないもどかしさが残ります。

いつも思います。
愛すべき対象が日本人女性だけでは物足りない。


英会話教室を探しました。
もちろん、お金に不自由している人なので、そこを優先的に探しました。

おー。あった。
http://www.rarejob.com/

直接の会話ってわけではないけども、スカイプを通して英会話のレッスンを受けることができます。


1週間やってみての感想。
・とにかく安い
        月5千円は破格です。
・毎日英語を話せる
        週1のレッスンより、上達が速い??

まだまだ会話がおぼつかないけども、早く英語をマスターしたいです。

ハッシュを定義する

ハッシュとは、配列と同じように任意の個数の値を格納するデータ構造の一つです。ただし、配列とは違って、格納する個々の値を指定するのに、数値 (index) の代わりに名前を使います。この名前をキーと言います。

name [1] = “Hanako”

indexである “1” の値に名前を使う事ができます。
下記のように表すことができます。

$name{“ Yamada “} = “Hanako”

“Yamada” がキー、”Hanako” が値になります。

配列はindexがユニークな値になっています。ハッシュでも、キーはユニークな値しか認められません。


ハッシュの要素にアクセス
要素にアクセスする場合は以下のように書きます。

$hash{$some_key}

具体例として、
$name{“Yamada”} = “Hanako”;
$name{“Suzuki”} = “Taro”;
$name{“Shindo”} = “Taichi”;


ハッシュの全体にアクセス
ハッシュ全体を表すには、”%”を使います。

%name = (“Yamada”, “Hanako”, “Suzuki”, “Taro”, “Shindo”, “Taichi” };

■ハッシュをほどく
Perlは、検索が速くできるような順番で、キーと値のペアを格納するため、リストに戻したさいに、元のリストとお同じ順番で並ぶとは限りません。

#!usr/bin/perl
%some_hash = ("Yamada", "Hanako", "Suzuki", "Taro", "Shindo", "Taichi");
@any_array = %some_hash;
print "@any_array\n";

実行してみる

$ perl 5_2_1
Yamada Hanako Shindo Taichi Suzuki Taro


■ => を使ってキー/値を定義する
人間にとって、どれがキーで、どれが値かを分かりやすくするために、”=>” を使います。

%name = (“Yamada” => “Hanako”, “Suzuki” => “Taro”, “Shindo” => “Taichi” };


関数を使う
ハッシュ全体を扱う関数がいくつかあります。

■keys ・ values
keys : ハッシュに含まれる全てのキーから成るリストを返します。
values : ハッシュに含まれる全ての値から成るリストを返します。

サンプルとしては下記の通りです。

%name = ("Yamada", "Hanako", "Suzuki", "Taro", "Shindo", "Taichi");

my @key = keys %name;
my @value = values %name;

print "\%nameのキー:@key\n";
print "\%nameの値:@value\n";

実行すると、下記が出力されます。
%nameのキー:Yamada Shindo Suzuki
%nameの値:Hanako Taichi Taro


■each
each : 評価するたびに、次のキー/値のペアを返します。繰り返しに利用されます。

サンプルとしては下記の通りです。

%name = ("Yamada", "Hanako", "Suzuki", "Taro", "Shindo", "Taichi");

while( ($key, $value) = each %name ) {
print "$key => $value\n";
}

実行すると下記が出力されます。
Yamada => Hanako
Shindo => Taichi
Suzuki => Taro

2011年4月5日火曜日

サブルーチンを定義する

Perlでは、ほかの言語と同様にサブルーチン (subroutine:ユーザ定義の関数) を定義することができます。これを利用することで、何度も再利用することが可能になります。

サブルーチンの定義
■下記のように定義します。

sub ${subrootine} {
        body;
}

sub と subrootineの名前を置き、その後ろにbody(コード)を置き、ブレースで囲みます。
例えば、以下のように書きます。

sub hello {
        print “Hello, Perl ! “;
]

■Perlのサブルーチンの特徴としては、下記に挙げるものです。
・サブルーチン定義は、プログラムファイルのどこに置いても構いません。
・サブルーチン定義は、特別な処理をしない限りグローバルです。
・同じ名前を持つサブルーチンが2つあると、後ろに置かれたものが、前に置かれたものを上書きします。


戻り値
■Perlでは、サブルーチンの戻り値を単純にしました。
つまり、サブルーチンの中で最後に行われた計算の結果を自動的に戻り値にしました。
例えば下記のコードを作成します。

#!usr/bin/perl

sub hello {
print "Hello Perl !\n";
$num1 + $num2;
}

$num1 = 1;
$num2 = 2;

$num3 = &hello;
print "\$num3 is $num3.\n";

$num4 = $hello;
print "\$num4 is $num4.\n";



結果は下記のとおりです。
Hello Perl !
$num3 is 3.
Hello Perl !
$num4 is 3.

つまり、$num1 + $num2 が戻り値になります。


■誤って、サブルーチンの最後の行にコードを加えてしまったらどうなるでしょう。

#!usr/bin/perl

sub hello {
print "Hello Perl !\n";
$num1 + $num2;
        
print “It is mistake!”;
}

$num1 = 1;
$num2 = 2;

$num3 = &hello;
print "\$num3 is $num3.\n";

$num4 = $hello;
print "\$num4 is $num4.\n";


結果は下記の通りです。
Hello Perl !
It is mistake!$num3 is 1.
Hello Perl !
It is mistake!$num4 is 1.

printの表示が成功したことを示す ” 1 “ の値が戻り値になっています。
$num1 + $num2 の値はどうなるのでしょうか?Perlはそれを捨ててしまいます。
もし、警告を有効にしておくと、下記のメッセージも出力されます。

Useless use of addition (+) in void context at subrountine_sample_1 line 5.


■最後に評価された式を返す
下記の式を見てみましょう。
subroutineで最後に評価される式としては、$num1もしくは$num2のどちらかです。

#!usr/bin/perl

sub larger_num1_or_num2 {
if ($num2 < $num1) {
$num1;
} else {
$num2;
}
}

$num1 = 1;
$num2 = 2;

$large_number = &larger_num1_or_num2;

print "\$large_number is $large_number.\n";



引数
サブルーチンに対して引数を渡すには、サブルーチンの直後にリスト式を置きます。
$n = larger_num1_or_num2(10 , 15);

この引数は、サブルーチンを実行している間、自動的に特別な配列変数@_に代入されます。

#!usr/bin/perl

sub larger_num1_or_num2 {
if ($_[1] < $_[0]) {
$_[0];
} else {
$_[1];
}
}

$large_number = &larger_num1_or_num2(10, 15);

print "\$large_number is $large_number.\n";


return演算子
サブルーチンの残りを実行せずに、即座に値を返すのが、Perlのreturn文の使い方です。

ハードコンタクトを好きになる瞬間

{diary}
ハードコンタクト、意図しない動きをするから嫌いです。
酔っぱらって外すと行方不明になるし、目をこすると瞳孔から逃げていきます。

もう2年近く使っているのに未だに困惑します。


今日、ユニットバスで外そうとすると、また僕のもとから逃げていきました。

「おいおい、またかよ」

30分近く探しても出てきません。

諦めました・・・

ふて寝しよー( ; - . - )

部屋に戻ると、彼がいるのです。


「ん?なんでここに?」

コンタクトがいなくなったとき、僕は急いで部屋に戻って眼鏡をつけ、探しに戻りました。

このときだな。


僕から離れずに服にしがみついていたんだ

なんて可愛いやつ

少し好きになった瞬間でした。

2011年4月4日月曜日

sudoコマンド

sudoは、一人の管理者に権限と責任が集中しているサーバ管理を、複数の管理者チームに権限と責任を分散させることが目的です。なぜなら、権限を集中させることは、リスクや管理者の負荷を大きくするからです。sudoを使うことによって、リスクや負荷を小さくすることができます。

sudoを取り入れることで、パスワード入力だけでスーパーユーザになれるといったセキュリティ上の問題があるsuコマンドを廃止にすることも可能です。


sudoの設定
■sudoの設定ファイルを見て分かるように、rootユーザでしか設定できません。

$ ls -al /etc/sudoers
-r--r----- 1 root root 3216 4月 2 10:03 /etc/sudoers

■それでは、shindo_tユーザにsudo権限を与えましょう。
75行目あたりに下記のように入力します。

$ visudo

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
## user MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
shindo_t ALL=(ALL) ALL

■実際にsudoコマンドを使いましょう。

$ sudo more /etc/sudoers
[sudo] password for shindo_t: ********* ←ここは、shindo_tのパスワードを入力します。


今回は紹介しなかったけども、sudoで与える権限を指定することもできます。
これも、visudoコマンドで /etc/sudoers の中身を書き換えるだけです。


アクセスログの確認

$ tail -n 5 /var/log/secure

Apr 4 22:44:06 lovemoe su: pam_unix(su-l:session): session opened for user root by shindo_t(uid=500)
Apr 4 22:52:01 lovemoe sudo: root : TTY=pts/1 ; PWD=/root ; USER=root ; COMMAND=/bin/more /etc/sudoers
Apr 4 22:52:17 lovemoe su: pam_unix(su-l:session): session opened for user shindo_t by shindo_t(uid=0)
Apr 4 22:52:34 lovemoe sudo: shindo_t : TTY=pts/1 ; PWD=/home/shindo_t ; USER=root ; COMMAND=/bin/more /etc/sudoers
Apr 4 22:56:57 lovemoe su: pam_unix(su-l:session): session opened for user root by shindo_t(uid=500)


このように、ユーザ追加・パスワード設定・ログイン/ログアウト・sudo利用状況が記録されます。


suの無効化
適切な設定をした後は、suコマンドを無効化することが推奨されています。su認証設定ファイル /etc/pam.d/su の5行目あたりに pam_deny.so モジュール認証行を追加するだけで su コマンドを無効にすることができます。
下記の赤字を入力します。

$ vi /etc/pam.d/su

# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth sufficient pam_wheel.so trust use_uid
auth required pam_deny.so


下記のように正しいパスワードを入力しても拒否されます。
$ su
パスワード: ****
su: incorrect password

2011年4月3日日曜日

tarコマンド

tar (tape archiver) コマンドは、1つまたは複数のファイルを保存するためのもの。UNIX関係のパッケージはこの tar + gzip 形式で提供されることが一般的。拡張子は “ .tar.gz ” または “ .tgz “ で、この拡張子ファイルを “ tarball ” と呼ぶ。

*ファイル保存をgzip圧縮で行う場合のtarコマンド例
        tar -cvzf ${ファイル名}.tar.gz file1 file2...

*tarファイルの解凍コマンド例
        tar -xvzf ${ファイル名}.tar.gz

2011年4月2日土曜日

memcachedのインストール

memcachedは、mixiやfacebookといったWebアプリケーションのスケーラビリティを向上させる重要な要素になります。memcachedは高性能な分散メモリキャッシュサーバで、データベースの問い合わせ結果を一時的にキャッシュすることで、データベースのアクセス回数を減らしています。そのことが、動的Webアプリケーションの高速化やスケーラビリティの向上につながっています。

memcachedをインストールする
参考)http://pentan.info/server/linux/memcached.html

$ cd /tmp
$ wget http://www.danga.com/memcached/dist/memcached-1.4.5.tar.gz
$ tar zxvf memcached-1.4.5.tar.gz
$ cd memcached-1.4.5
$ ./configure
$ make
$ make install

(*) ./configureでlibeventが必要と言われたからそれをインストールしました。
mekeコマンドでターゲットが見つかりません、と言われたら ./configureで必要なライブラリを持って来れていない、ということだから、必要なライブラリをインストールする必要があります。

起動させる
$ /usr/local/bin/memcached -p 11211 -m 64m -vv

(*)rootユーザでは実行できないことに注意


perlでmemcachedと連携
参考)http://gihyo.jp/dev/feature/01/memcached/0001?page=3

$ cpan
cpan > install Cache::Memcached

任意のフォルダに移動して、以下のソールファイルを置く

#!/usr/bin/perl

use strict;
use warnings;
use Cache::Memcached;

my $key = "foo";
my $value = "bar";
my $expires = 3600; # 1 hour
my $memcached = Cache::Memcached->new({
servers => ["127.0.0.1:11211"],
compress_threshold => 10_000
});

$memcached->add($key, $value, $expires);
my $ret = $memcached->get($key);
print "$ret\n";

正常にmemcachedが動いていれば、perlを実行した時、”bar” が表示されます。