perl: 2007年11月アーカイブ

前回の続き。今度は、ブラウザで表示できるようにしてみた。

sh-3.00$ cat example2.pl
#!/usr/bin/perl
#print "Content-type: text/html;\n\n";
print "Content-type: text/html; charset=UTF-8\n\n";
print "<HTML>\n";
print "<BODY>\n";
$hr = "-" x 96;
$time = localtime;

print "$hr<BR>\n";
print "$time のディスク使用量<BR>\n";
print "\n";
print "<pre>\n";
system("/bin/df -h");
print "</pre>\n";
print "\n";

print "$hr<BR>\n";

print "$time のメモリ使用状況<BR>\n";
print "\n";
print "<pre>\n";
system("/usr/bin/free");
print "</pre>\n";
print "\n";

print "$hr<BR>\n";

print "CPU使用率<BR>\n";
print "\n";
print "<pre>\n";
system("LANG=C /usr/bin/sar -u 1 10");
print "</pre>\n";
print "\n";

print "$hr<BR>\n";

print "<BR>\n";
print "</BODY>\n";
print "</HTML>\n";


ブラウザで実行した結果は以下の通り。

------------------------------------------------------------------------------------------------
Fri Nov 16 20:49:52 2007 のディスク使用量

Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                       66G  1.3G   61G   3% /
/dev/sda1              99M   24M   71M  25% /boot
none                 1014M     0 1014M   0% /dev/shm
/dev/sdb1              68G  355M   64G   1% /home

------------------------------------------------------------------------------------------------
Fri Nov 16 20:49:52 2007 のメモリ使用状況

             total       used       free     shared    buffers     cached
Mem:       2075952     834476    1241476          0     106752     581424
-/+ buffers/cache:     146300    1929652
Swap:      2031608          0    2031608

------------------------------------------------------------------------------------------------
CPU使用率

Linux 2.6.9-55.0.12.EL (nullpopopo.blogcube.info)     11/16/07

20:49:52          CPU     %user     %nice   %system   %iowait     %idle
20:49:53          all      0.00      0.00      0.00      0.00    100.00
20:49:54          all      0.00      0.00      0.00      0.00    100.00
20:49:55          all      0.00      0.00      0.00      0.00    100.00
20:49:56          all      0.00      0.00      0.00      0.00    100.00
20:49:57          all      0.99      0.00      0.00      1.98     97.03
20:49:58          all      0.00      0.00      0.00      0.00    100.00
20:49:59          all      0.00      0.00      0.00      0.00    100.00
20:50:00          all      0.00      0.00      0.00      0.00    100.00
20:50:01          all      0.99      0.00      0.99      4.95     93.07
20:50:02          all      4.90      0.00     11.76      0.00     83.33
Average:          all      0.70      0.00      1.30      0.70     97.31

------------------------------------------------------------------------------------------------
時刻表示は、unixのdateコマンドより楽かも知れない。
今日のネタは、これ。

sh-3.00$ cat example1.pl
#!/usr/bin/perl

print "------------------------------\n";

$data = localtime;
print "現在時刻を表示する\n";
print "$data\n";

print "------------------------------\n";

$time = time;
print "現在時刻をUNIXTIMEで表示する\n";
print "$time\n";

print "------------------------------\n";

$gmtime = gmtime(time + 0);
print "現在時刻をGMTで表示する\n";
print "$gmtime\n";

print "------------------------------\n";


実行結果は以下の通り。

sh-3.00$ ./example1.pl
------------------------------
現在時刻を表示する
Wed Nov 14 23:00:10 2007
------------------------------
現在時刻をUNIXTIMEで表示する
1195048810
------------------------------
現在時刻をGMTで表示する
Wed Nov 14 14:00:10 2007
------------------------------

今日もトゴシくんは虐められてます。
まるでスチュワーデス物語における、堀ちえみのような扱いです。
そんなトゴシくんの日常を、スクリプトにしてみました。

※ ホントは今日、会社はおやすみでした。

join関数で、配列中のデータの区切りを指定して表示してみます。

sh-3.00$ cat example1.pl
#!/usr/bin/perl

@data = ("ドジ","ノロマ");
$comment = join("で",@data);
print "とごしは $comment な亀である\n";
exit;

実行結果は以下の通りです。

sh-3.00$ ./example1.pl
とごしは ドジでノロマ な亀である



おまけにもう1つ


sh-3.00$ cat example2.pl
#!/usr/bin/perl

$data[0] = ("コーラ");
$data[1] = ("めろんぱん");
$comment = join("と",@data);
print "おい、とごし $comment 買って来い。\n";
exit;

実行結果は以下の通りです。

sh-3.00$ ./example2.pl
おい、とごし コーラとめろんぱん 買って来い。

perlでのgrep関数を使ってみた。意外と簡単。
プログラムは以下の通り。

sh-3.00$ cat grep01.pl
#!/usr/bin/perl
@array = ("apple", "application","pineapple","wine","windows");
$count = grep(/app/, @array);
@items = grep(/app/, @array);
print "件数は$count、内容は@items。\n";

appを含むものを引っ掛けてその件数と内容を表示する。

sh-3.00$ perl grep01.pl
件数は3、内容はapple application pineapple。



次に、先頭文字がappのものを引っ掛けてその件数と内容を表示する。

sh-3.00$ cat grep02.pl
#!/usr/bin/perl
@array = ("apple", "application","pineapple","wine","windows");
$count = grep(/^app/, @array);
@items = grep(/^app/, @array);
print "件数は$count、内容は@items。\n";

実行結果は以下の通り。

sh-3.00$ perl grep02.pl
件数は2、内容はapple application。



そして、大文字小文字を区別せずに検索してみる。

sh-3.00$ cat grep03.pl
#!/usr/bin/perl
@array = ("Apple", "aPPlication","piNeapple","wine","windows");
$count = grep(/app/i, @array);
@items = grep(/app/i, @array);
print "件数は$count、内容は@items。\n";

実行結果は以下の通り。

sh-3.00$ perl grep03.pl
件数は3、内容はApple aPPlication piNeapple。



「あなたのお名前なんてーの?」という質問に対して、自分の名前を回答する。
プログラムはこう。

#!/usr/bin/perl

print "What\'s your name ?";
$name = <STDIN>;  #画面からの入力
chomp($name);
print "$name is your name.\n";

実行結果
$ perl name.pl
What's your name ?togoshi ← togoshiと入力する
togoshi is your name.

ここでミソなのは、chompを使うことで、いらん改行を発生させないこと。
chompがないと、実行結果は以下のようになる。

$ perl name.pl
What's your name ?togoshi
togoshi
 is your name.


佐藤さん、鈴木さん、田中さん、吉田さんを一気に表示したいとき、配列変数を使うと楽ちんです。

配列変数を使わない例 ← まつがい
配列変数を一個一個使う例

#!/usr/bin/perl

$name[0] = "satou";
$name[1] = "suzuki";
$name[2] = "tanaka";
$name[3] = "yoshida";

print "$name[0]\n";
print "$name[1]\n";
print "$name[2]\n";
print "$name[3]\n";




配列変数を使った例

#!/usr/bin/perl

$name[0] = "satou";
$name[1] = "suzuki";
$name[2] = "tanaka";
$name[3] = "yoshida";

foreach ( @name ){    # $_に一行ずつ代入

    print ;     # $_ の内容を出力
    print "\n";

}




配列変数をひとまとめにして使ったほうが楽ちんですね。
というわけで、今日は配列変数を覚えました。飴ちゃんありがとう!
業務で使うネタを教材にして勉強していけば、やった結果が目に見えてわかるだろうと思った。
まずは、UNIXコマンドでいうところのgrepとsedをperlでやってみた。

※さっきウソ書いてしまいました。
$ perl -ne 'print if (m/session (opened|closed)/)' /var/log/messages
$ perl -ne 'print if (m/session [opened|closed]/)' /var/log/messages

[]でくくっちゃうと、「session odc」なんていうログも引っ掛けてしまうので、
単語単位でひっかけたいなら、文字クラス「[]」ではなく、パターングループ「()」で
引っ掛けるべきなのですね。


■ メールのログから、送信成功の行を抜き出す

$ perl -ne 'print if (m/sent/)' /var/log/maillog
Nov  8 06:00:02 intra1 postfix/local[12546]: DC72F8F839C: to=<root@intra1.example.com>, orig_to=<root>, relay=local, delay=1, status=sent (forwarded as 01DEA8F8392)
Nov  8 06:00:02 intra1 postfix/smtp[12548]: 01DEA8F8392: to=<shasta@example.info>, orig_to=<root>, relay=mx.example.info[192.168.0.2], delay=0, status=sent (250 Ok: queued as 1BF4C76873C)
Nov  8 07:31:33 intra1 postfix/local[16078]: 5AFB38F8057: to=<root@intra1.example.com>, orig_to=<root>, relay=local, delay=0, status=sent (forwarded as AE9F58F824E)
Nov  8 07:31:34 intra1 postfix/smtp[16079]: AE9F58F824E: to=<shasta@example.info>, orig_to=<root>, relay=mx.example.info[192.168.0.2], delay=1, status=sent (250 Ok: queued as EF4807681A1)
Nov  8 09:01:01 intra1 postfix/local[19426]: 9620E8F8392: to=<shasta@intra1.example.com>, orig_to=<shasta>, relay=local, delay=0, status=sent (forwarded as A91608F839C)
Nov  8 09:01:01 intra1 postfix/local[19424]: 8F0DA8F83BB: to=<root@intra1.example.com>, orig_to=<root>, relay=local, delay=0, status=sent (forwarded as B02E18F8392)
・・・


■ 正規表現を使って、sshでのログイン|ログアウトの履歴を抜き出す

$ perl -ne 'print if (m/session (opened|closed)/)' /var/log/messages
Nov  8 15:39:31 intra1 sshd(pam_unix)[1709]: session opened for user shasta by (uid=0)
Nov  8 15:40:24 intra1 su(pam_unix)[1926]: session opened for user root by shasta(uid=1000)
Nov  8 15:46:06 intra1 su(pam_unix)[1926]: session closed for user root
Nov  8 15:46:06 intra1 sshd(pam_unix)[1709]: session closed for user shasta
Nov  8 15:48:15 intra1 sshd(pam_unix)[2722]: session opened for user shasta by (uid=0)
Nov  8 15:48:28 intra1 su(pam_unix)[2947]: session opened for user root by shasta(uid=1000)
Nov  8 15:48:46 intra1 su(pam_unix)[2947]: session closed for user root
Nov  8 15:48:54 intra1 sshd(pam_unix)[2722]: session closed for user shasta
・・・


■ ログの日付を置換してみる

元のログ
Nov  8 04:02:11 intra1 syslogd 1.4.1: restart.
Nov  8 04:02:26 intra1 clamd[2689]: Database correctly reloaded (299083 signatures)

$ perl -ne 'print if (s/Nov  /11\//)' /var/log/messages
11/8 04:02:11 intra1 syslogd 1.4.1: restart.
11/8 04:02:26 intra1 clamd[2689]: Database correctly reloaded (299083 signatures)
置換後は上記のようになった


■ ログの小文字を大文字にしてみる

元のログ
Nov  8 04:02:11 intra1 syslogd 1.4.1: restart.
Nov  8 04:02:26 intra1 clamd[2689]: Database correctly reloaded (299083 signatures)

$ perl -ne 'print if (tr/a-z/A-Z/)' /var/log/messages
NOV  8 04:02:11 INTRA1 SYSLOGD 1.4.1: RESTART.
NOV  8 04:02:26 INTRA1 CLAMD[2689]: DATABASE CORRECTLY RELOADED (299083 SIGNATURES)
置換後は上記のようになった

perlで、文字列の表示と逆順表示(っていうの?)を教わった。

例えば
aiueo
oeuia

と表示したり

あいうえお
おえういあ

と表示したり。

#! /usr/bin/perl

use utf8;
binmode STDOUT, ":utf8";

$str = "あいうえお";

print "$str\n";

$str = reverse($str);

print "$str\n";


それと、単語を指定回数繰り返すのを教わった。
#! /usr/bin/perl

$str = "hello" x 3;

print "$str\n";

こうすると、
hellohellohello
と表示される。

「これができるのって、Perlくらいじゃないかなぁ」とのことだったので、
負けず嫌い(?)なおいらは、awkでやってみたw

$ echo hello | awk '{print $1$1$1}'
hellohellohello

けど、都度繰り返しの回数を変えたいときなどは、きっとPerlのほうがスマートにできそうな気がする。
もっともっと勉強しなきゃ。


どんなモジュールが入っているかを一覧にしてみた。
ググってみたら、そのものズバリな答えがあったので、
ブラウザでちゃんと改行して表示されるようになおしてみた。
中身はこう。

#! /usr/bin/perl
use strict;

my %mod_list;

print "Content-type: text/html;\n\n";
print "<html><body>";

listup($_) for grep {$_ ne '.'} @INC;
print "$_\<br\>\n" for sort keys %mod_list;
sub listup {
  my ($base, $path) = @_;
  (my $mod = $path) =~ s!/!::!g;

  opendir DIR, "$base/$path" or return;
  my @node = grep {!/^\.\.?$/} readdir DIR;
  closedir DIR;

  foreach (@node) {
    if (/(.+)\.pm$/) { $mod_list{"$mod$1"} = 1 }
    elsif (-d "$base/$path$_") { listup($base, "$path$_/") }
  }
}
print "</body></html>";

飴ちゃんにいろいろ教わってます。
まだ自分で課題見つけることができないので、
飴ちゃんのお題をこなすのがいい教材です。

自分のレベルはどんくらい?という指標が
http://d.hatena.ne.jp/naoya/20050809/1123563794
にあったので見てみたら、当然レベル1にも満たないわけで。

でもがんがる!(`・ω・´)シャキーン
カスタム検索

カレンダー



このアーカイブについて

このページには、2007年11月以降に書かれたブログ記事のうちperlカテゴリに属しているものが含まれています。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

perl: 2007年11月: 月別アーカイブ

Powered by Movable Type 4.01