I ♥ WordPress

[時間割:Perl]『ミニマルPerl』その9
2008/11/12 01:48 posted by kunkichi

ここんところちょっと仕事が忙しくて帰ってきたら勉強する気ゼロなことが多いんですが、そんな中最近の一番の勉強スポットはお風呂だったりしてます。いやー、高い本は気を使いますw

ということで、昨日月曜日の『Perl』の時間の成果をアップします。引き続きsed編。sed編はこれが最後です。

ミニマルPerl Unix/LinuxユーザのためのPerl習得法
Tim Maher
オライリージャパン
売り上げランキング: 96883
  • 大文字小文字変換用の文字列修飾子$ echo "abc" | perl -wpl -e 's/^.*$/\U/g;' ← 大文字変換
    ABC
    $ echo "ABC" | perl -wpl -e 's/^.*$/\L/g;' ← 小文字変換
    abc
    あと、\u と \l は隣の1文字だけを変換。
  • \E で \Uや\Lを終了する。$ perl -e 'print "this is \Ucapital\E letters.\n";'
    this is CAPITAL letters.
  • 文字列修飾子は一部のコンテキストでのみ使える。ダブルクォートされた文字列、マッチングや置き換えの場合とか。
  • 置換演算子 e で 置き換えた後の文字列をコードで生成することができる(e は eval の e)これを使えば置換で計算とかができる。$ echo "20 miles 14" | perl -wp -e 's/^(\d+) miles$/$1 * 1.6 . " km"/e;'
    32 km
  • 関数を使って置き換えたり。Text::Tabsのexpand関数を使って、タブを4つのスペースに置き換えてみる。$ echo "this  is  a  tab-separeted sentence." | perl -wp -MText::Tabs -e '$tabstop = 2; s/^.*$/expand $&/eg'
    this  is  a tab-separeted sentence.

次はawkです。これで文字列処理系のコマンドは全部置き換えられちゃうなー。

[時間割:C言語]『はじめてのC言語完全入門』その10
2008/11/09 00:27 posted by kunkichi

ここ2、3日格闘していた、ポインタですが、なーんとなく少し壁は超えれたような気がするので、わかってるところだけでもちょっとまとめてみます。あくまでも、なーんとなくのレベル。

はじめてのC言語 完全入門 (標準プログラマーズライブラリ)
塚越 一雄
技術評論社
売り上げランキング: 420963


ポインタ

  • 変数は値を記憶する。ポインタ変数はアドレスを記憶する。
  • 宣言する場合は、変数名の前に*をつける。あと、ポインタにも型は必要。int *pval;
  • ポインタで指定されるアドレスは先頭アドレス。そこから何バイトのデータなのかを判断するために、「型」が必要。(型がわかればバイト数がわかる。sizeof(int)とか)。つまりポインタは型情報を持つということ。
  • ポインタへの代入は当たり前だけどアドレスを代入する。通常はアドレス演算子&を使う。変数に&をつけると、その変数の値ではなく、アドレスを参照する。int *pval;
    int val;
    pval = &val;
  • ポインタがさしている別の変数のアドレスから、値を参照する場合は、*を使って逆参照する。int val = 10;
    int *pval;
    pval=&val;
    printf("%d¥n",*pval);
    結果は”10″が出力される。
  • Cの関数では、実引数の値は仮引数にコピーされるため、関数内でどうこうしたとしても実引数には影響しない。つまり、スコープの話。
  • 関数内で実引数を直接変更したい場合はポインタ引数を使う。
    関数の宣言:void pointer_func( int *x, int *y )関数の呼び出し:pointer_func( &a, &b )関数内で値を参照:int val = *a;
  • アドレスを返すような関数でエラーを返す場合はNULLポインタを使う。

配列とポインタ

  • 配列の名前は、配列の先頭アドレスを意味するので、ポインタに代入できる。int ary[] = { 1, 2, 3 };
    int *pval;
    pval = ary;
  • 配列の先頭アドレスは、配列の最初の要素の先頭アドレスでもある。つまり、ポインタに代入した後、逆参照すれば、最初の要素の値を取得できる。※上の続き
    printf("%d¥n", *pval);
    結果は1となり、ary[0]の値となる。
  • ポインタで演算をすると、そのポインタの型が使用するメモリサイズ分だけ加算される。#include <stdio.h>
     
    int main()
    {
      int *p;
      printf("%p\n", p );
      p += 1;
      printf("%p\n", p );
     
      return 0;
    }
    結果は0x1000
    0×1004
    となる。
  • 上記を配列で使うと、2番目以降の要素の参照ができる。#include <stdio.h>
     
    int main()
    {
      int ary[] = {
        1,
        5,
        8
      };
      int *p;
     
      p = ary;
     
      printf("%p:%d\n", p,   *p     );
      printf("%p:%d\n", p+1, *(p+1) );
      printf("%p:%d\n", p+2, *(p+2) );
     
      return 0;
    }
    結果:0xbffff9f0:1
    0xbffff9f4:5
    0xbffff9f8:8
    アドレスは4バイトずつ(僕の環境では)増えて、配列の要素を順に参照している。
  • 上の例では参照するポインタを直接指定していたけど、ループを使ってポインタの値をインクリメントしながら参照してみる。#include <stdio.h>
     
    int main()
    {
      int ary[] = {
        1,
        5,
        8
      };
      int *p;
     
      p = ary;
     
      int i;
      for( i=0; i<(sizeof ary / sizeof ary[0]); i++ )
        printf( "%d:%p:%d\n", i, p, *p++ );
     
      return 0;
    }
    結果は同じ0:0xbffff9f0:1
    1:0xbffff9f4:5
    2:0xbffff9f8:8
  • ポインタを配列のように使う。上の例のforループの部分を以下のように書き換えてみる。  for( i=0; i<(sizeof ary / sizeof ary[0]); i++ )
        printf( "%d:%p:%d\n", i, &p[i], p[i]);
    結果はこれまた同じ。0:0xbffff9ec:1
    1:0xbffff9f0:5
    2:0xbffff9f4:8
    つまり、配列のようにインデックスで指定して、元の配列要素の値を取得できる。
  • 今度は逆に配列をポインタのように使う。include <stdio.h>
     
    int main()
    {
      int ary[] = {
        1,
        5,
        8
      };
     
      int i;
      for( i=0; i<(sizeof ary / sizeof ary[0]); i++ )
        printf( "%d:%d\n", i, *(ary+i) );
     
      return 0;
    }
    結果はこうなる。0:1
    1:5
    2:8
    配列の各要素に、ポインタで使った逆参照演算子*を使って値を参照することができる。
  • 配列とポインタの違いは、
    • ポインタは変数であり、メモリ上にアドレスを記録するための領域が確保される。従って値を変更することができる。
    • 配列名は、コンパイラがコンパイル中に使用する「定数」なので、メモリ上に配列名を記憶するための領域は確保されない(ただし配列の各要素を記録するための領域は確保される)。従って、値を変更することができない。
  • 関数の引数に配列を渡す場合は配列名だけを渡す。int ary[];
    sample func(ary)
  • 関数側の受け取り方は以下の2パターン。配列の要素から最大値を求めるmaxという関数をそれぞれのパターンで書いてみる。
    • 配列で受け取る。例:
      int sample_function(int a[]){
      ・・・
      }
      サンプルコード:#include <stdio.h>
       
      int max(int a[], int size);
       
      int main()
      {
        int ary[] = {
          1,
          5,
          8
        };
        int val;
        val = max( ary, sizeof ary / sizeof ary[0]);
        printf("%d\n",val);
        return 0;
      }
       
      int max(int a[], int size)
      {
        int max = a[0];
        int i;
        for(i = 1;i<size;i++)
          if(max < a[i])
            max = a[i];
        
        return max;
      }
    • ポインタで受け取る。
      例:int sample_function(int *a){
      ・・・
      }
      サンプルコード:#include <stdio.h>
       
      int max(int *a, int size);
       
      int main()
      {
        int ary[] = {
          1,
          5,
          8
        };
        int val;
        val = max( ary, sizeof ary / sizeof ary[0]);
        printf("%d\n",val);
        return 0;
      }
       
      int max(int *a, int size)
      {
        int max = a[0];
        int i;
        for(i = 1;i<size;i++)
          if(max < a[i])
            max = a[i];
        
        return max;
      }
  • 配列を関数に渡す場合、渡されるのは配列の先頭アドレスだけなので、配列の要素数については別に渡してあげる必要があるので注意。上記の例で、関数の引数に配列だけじゃなくて、配列も渡しているのはそのため。試しに配列の要素数を返す関数を作って試してみる。#include <stdio.h>
     
    int arynum(int a[]);
     
    int main()
    {
      int ary[] = {
        1,
        5,
        8
      };
      int val;
      
      val = arynum( ary );
      printf("%d\n",val);
      printf("%d\n",sizeof ary / sizeof ary[0]);
      return 0;
    }
     
    int arynum(int a[])
    {
      int num;
      num = sizeof a / sizeof a[0];
      return num;
    }
    結果は以下。1
    3

ふぅー、途中ちょっと別の本も読んでみたりしつつでしたが、何度か繰り返し読んで、サンプルコードを自分で書いてみて、そんなこんなしてるうちに何となくわかってきました。やっぱり「何度も読む」ことで見えてこなかったものが少しずつ見えてくるんだよね。とりあえず最大の難関を終えてホッとしました。

次回は「文字列と文字配列」です。

[時間割:サーバ] CentOS5.2 で Ruby on Rails をインストールして、プロジェクト管理ツール『9arrows』を試してみる
2008/11/07 02:40 posted by kunkichi

水曜日は『サーバ』の時間です。今日はちょっと趣向を変えて、「9Arrows」というプロジェクト管理ツールを試してみようということで、それを動かすのに必要な「Ruby on Rails」のインストールにトライしてみたいと思います。でもRailsはさっぱりわからないので、9Allowsが最低限動けばOKとします。環境はもちろん CentOS5.2。OSのインストールからの最短手順を目指します。

OSインストール

  • MacBook上のParallelsにインストール。
  • テキストインストール。
  • パッケージはベースシステムのみの最短構成から。
  • ファイアウォールとSELinuxは停止しておく。
  • インストールが終わったら一旦 yum update で最新の状態にしておく。

epelパッケージインストール
RailsのパッケージがEPELにあるのでこれを使うために、まずepelを使えるようにする。

  • epel-releaseをインストール# wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
    # rpm -ivh epel-release-5-3.noarch.rpm

Ruby on Railsパッケージインストール

  • EPELのRailsのパッケージをインストールする。# yum install rubygem-railsこれで必要なパッケージは全部インストールされるっぽい↓Dependencies Resolved
     
    =============================================================================
    Package                 Arch       Version          Repository        Size
    =============================================================================
    Installing:
    rubygem-rails           noarch     2.1.1-2.el5      epel              428 k
    Installing for dependencies:
    ruby                    i386       1.8.5-5.el5_2.5  updates           279 k
    ruby-irb                i386       1.8.5-5.el5_2.5  updates            69 k
    ruby-libs               i386       1.8.5-5.el5_2.5  updates           1.6 M
    ruby-rdoc               i386       1.8.5-5.el5_2.5  updates           136 k
    rubygem-actionmailer    noarch     2.1.1-1.el5      epel              455 k
    rubygem-actionpack      noarch     2.1.1-1.el5      epel              2.1 M
    rubygem-activerecord    noarch     2.1.1-1.el5      epel              1.4 M
    rubygem-activeresource  noarch     2.1.1-1.el5      epel              176 k
    rubygem-activesupport   noarch     2.1.1-1.el5      epel              1.3 M
    rubygem-rake            noarch     0.7.3-2.el5      epel              320 k
    rubygems                noarch     1.2.0-2.el5      epel              617 k
     
    Transaction Summary
    =============================================================================
    Install     12 Package(s)        
    Update       0 Package(s)        
    Remove       0 Package(s)        
     
    Total download size: 8.9 M
    Is this ok [y/N]:
    ただし、rakeのバージョンが低すぎてRailsでエラーになる様子。# rails -v
    /usr/lib/ruby/site_ruby/1.8/rubygems.rb:578:in `report_activate_error': RubyGem version error: rake(0.7.3 not >= 0.8.1) (Gem::LoadError)
    なので、rakeだけはgemsからインストールする。最新版のrakeをインストールしてみる。# gem install rake --version 0.8.3確認# gem list
    *** LOCAL GEMS ***
     
    actionmailer (2.1.1)
    actionpack (2.1.1)
    activerecord (2.1.1)
    activeresource (2.1.1)
    activesupport (2.1.1)
    rails (2.1.1)
    rake (0.8.3, 0.7.3)

その他のパッケージのインストール
9Arrowsが必要とする他のパッケージをインストールする。

  • apache# yum install httpd
    # chkconfig httpd on
    # service httpd on
  • PostgreSQL# yum install postgresql-server ruby-postgres
    # chkconfig postgresql on
    # service postgresql start
    このままだとローカルホストからIDENT認証しかできず結果的にRailsから接続できないので、/var/lib/pgsql/data/pg_hba.confを編集する。# vi /var/lib/pgsql/data/pg_hba.conf
    ---–
    #host    all         all         127.0.0.1/32          ident sameuser
    host    all         all         127.0.0.1/32          password
    ---–
    再起動# service postgresql restart

9arrowsのインストール&設定
では9arrowsをインストール&設定していきます。

  • ソースをダウンロードします。ここではsvnレポジトリから最新版をチェックアウトしてみます。# yum install subversion
    # svn checkout http://9arrows.googlecode.com/svn/trunk/ 9arrows-read-only
  • チェックアウトしたディレクトリを適当なところに設置します。うちの場合は/var/www配下に設置しました。# cp -pir 9arrows-read-only /var/www/9arrows
  • パーミッションを変更します。アーカイブ内のディレクトリは既に755になっているようなので、必要な箇所だけ変更。# cd /var/www/9arrows
    # chmod 777 log public/attach public/javascripts/comp tmp tmp/{cache,pids,sessions,sockets}
  • httpd.confを設定します。# vi /etc/httpd/conf.d/9arrows.conf Railsのチュートリアルを参考に以下のような設定をしました。<VirtualHost *:80>
      ServerName 10.211.55.3
      DocumentRoot /var/www/9arrows/public/
      ErrorLog /var/www/9arrows/log/9arrows_error.log
      CustomLog /var/www/9arrows/log/9arrows_access.log combined
     
      <Directory /var/www/9arrows/public/>
        Options ExecCGI FollowSymLinks
        AddHandler cgi-script .cgi
        AllowOverride all
        Order allow,deny
        Allow from all
      </Directory>
    </VirtualHost>
    終わったらhttpdを再起動します。# service httpd restart
  • 公開ディレクトリである public にアクセスしたときに参照される dispatch.cgi に実行権がついていないのと、dispatch.cgi内のrubyのパス(/usr/local/bin/ruby)がCentOS5.2のruby(/usr/bin/ruby)のパスと異なっているので、シンボリックリンクで対応します。# chmod +x public/dispatch.cgi
    # ln -s /usr/bin/ruby /usr/local/bin/ruby
  • config/environment.rb に記載されている Rails のバージョン(2.1.0)が、パッケージでインストールしたRailsのバージョンと異なるので、パッケージのバージョンに合わせます。# vi config/environment.rb
    RAILS_GEM_VERSION = '2.1.1' unless defined? RAILS_GEM_VERSION
  • データベースの設定を行います。まずユーザとデータベースの作成。# su - postgres
    $ createuser 9arrows -P
    $ createdb 9arrows_test -O 9arrows
    $ createdb 9arrows_production -O 9arrows
    $ createdb 9arrows_development -O 9arrows
    次にconfig/database.ymlを編集してデータベース名・ユーザ名・パスワードを設定する。# vi config/database.yml
    ---–
    development:
      adapter: postgresql
      database: 9arrows_development
      username: 9arrows
      password: 9arrows
      host: localhost
    ---–
    設定ができたら、rakeコマンドでデータベースの初期化を行います。# rake db:migrate
    rake db:fixtures:load

ブラウザからアクセス
ここまでできたら、ブラウザからアクセスしてみます。

  • ログイン画面が出たら以下のIDとPWでログイン。
    ID 9arrows@example.com
    PW 9arrows

ログイン画面が出れば完了です。

今回はParallelsで構築したのでパフォーマンス的にはちょっと難しい感じですが、ちゃんとしたサーバで構築すれば問題ないと思います。あと、とりあえずメールについてはスルーしましたけど、きちんと設定すれば期限が来たらメール送信等もできるみたいですし、他にもAdobe AIRを使用すると、サーバにアクセスできなくてもクライアントだけで編集等もできるようなので、結構使い勝手はよさそうですね。

Rails全く知らなくてもなんとかなるもんですね。なんとなく雰囲気はわかった気がしました。

[時間割:Perl]『ミニマルPerl』その8
2008/11/05 02:49 posted by kunkichi

昨日は祝日で外に遊びにいってたのですが、一応ノルマは守りました。ということで月曜日の『Perl』の勉強成果をアップ。引き続き、sedをPerlで置き換えてみます。

ミニマルPerl Unix/LinuxユーザのためのPerl習得法
Tim Maher
オライリージャパン
売り上げランキング: 96883
  • テンプレート的に使う。以下のようなメールの雛形ファイルがあるとして、From: %%FROM%%<%%ADDR%%>
    To: %%TO%%
    Subject: [%%LEVEL%%] %%SUBJECT%%
     
    %%CONTENTS%%
     
    ------------------------------
    This mail is automatically sent.
    これを置き換えるスクリプトをmake_mail.plとする。内容は以下#!/usr/bin/perl -s -wpl
     
    s/ %%FROM%%     /$from/xg;
    s/ %%ADDR%%     /$addr/xg;
    s/ %%TO%%       /$to/xg;
    s/ %%LEVEL%%    /$level/xg;
    s/ %%SUBJECT%%  /$subject/xg;
    s/ %%CONTENTS%% /$contents/xg;
    で実行するコマンドは以下。$ ./make_mail.pl -from='kunkichi' -addr='kunkichi@example.com' -to='admin@example.com' -level='CRITICAL' -subject='SERVER DOWN!!!' -contents='Server is down at 10:25. Please Check!!!' mail.tpl出力結果:From: kunkichi <kunkichi@example.com>
    To: admin@example.com
    Subject: [CRITICAL] SERVER DOWN!!!
     
    Server is down at 10:25. Please Check!!!
     
    ------------------------------
    This mail is automatically sent.
    -sで引数を変数として取る。正規表現でxを使って正規表現中にスペースを含めるので、読みやすい。ただし、変換前文字だけ。
  • 特殊文字のマッチングを使って変換もできる。8進数→ASCII文字とか、\c制御文字とか。
  • -iを使って、編集元のファイルを直接変換&バックアップ。$ perl -i.BAK -wpl -e 's/aaa/bbb/g;' sample.txtオリジナルファイルは、sample.txt.BAKとしてリネームされて、sample.txtに変換後の結果が上書きされる
  • -iを使う場合は、-p、もしくは-n&printを使わないと、ファイルに何も出力されない、空ファイルができるので、注意!
  • スクリプト化しても便利。#!/usr/bin/perl -s -i.BAK -wpl
    s/$re/$after/g;
    -sでオプションを取ってオリジナルファイルを変換、元ファイルは.BAKをつけてリネーム。
  • 正規表現でx修飾子を使うと、スペースだけじゃなくてコメントも入れれる。s/
      ^          # 行頭が
        aaa     # aaaで始まり
        .*        # 任意の文字が0回以上続いて
        bbb    # bbbで
      $          # 行末が終わる
    /changed/gx; # ところを"changed"に置き換える。
  • -iを使ってバックアップをとっても、同じことを2回実行すると、結局元々のオリジナルは失われてしまう(バックアップがバックアップで上書きされる)。こういう場合は、-iの拡張子に毎回異なるもの、例えばシェル変数で時間とか、を指定すれば何回実行してもOK。例えば$SECONDSで、シェル起動後の秒数とか。$ perl -i.$SECONDS -wpl -e 's/aaa/bbb/g;' sample.txt
  • -iで拡張子を指定する代わりに、-iを単体で使って、$^Iという拡張子を示す特殊変数に拡張子を指定することもできる。例えばPIDとか。#!/usr/bin/perl -i -wpl
    BEGIN{ $^I=$$; }
    s/aaa/bbb/g;
    ただしこれはコマンドラインからの実行では、$$はシェルで展開されてシェルのPIDが入ってくるので、同じシェルで2回実行すると全く意味が無くなる。あくまでもスクリプト内で使う。

sedのところは残り少しです。

[時間割:C言語]『はじめてのC言語完全入門』その9
2008/11/04 00:34 posted by kunkichi

ここ2、3日の間、ポインタと格闘していました。ポインタ単体の意味は理解できるのだけど、配列とごっちゃになった瞬間もうわかりません、、、他の言語と比べると、C言語ではどうも配列とポインタの区別が曖昧な印象があるんだよね。

これはちょっとまずいってんで、その部分だけもう少ししっかり勉強しようと言うことで、教科書増やしました。

C言語配列+ポインタよくわかる実践学習室 (標準プログラマーズライブラリシリーズ)
谷尻 かおり 谷尻 豊寿
技術評論社
売り上げランキング: 209427


C言語ポインタ完全制覇 (標準プログラマーズライブラリ)
前橋 和弥
技術評論社
売り上げランキング: 9027


両方ともヤフオクでゲットしたので比較的懐を痛めずに済みました(笑)

ここまでの印象では他言語と特に大きく変わるところもなかったし、特につまずいたところもなかったのですが、ここはC言語の一番の山場っぽいので苦戦しそうです。もう少し格闘してみたいと思います。

[時間割:Perl]『ミニマルPerl』その7
2008/10/31 02:40 posted by kunkichi

今日も外で勉強してきました。やっぱり外はいいですね。ということで木曜日は『Perl』です。今回からsedをPerlで置き換えてみようというところです。

ミニマルPerl Unix/LinuxユーザのためのPerl習得法
Tim Maher
オライリージャパン
売り上げランキング: 96883
  • おなじみの置換。sedとほとんど同じ。$ echo "abcde" | perl -wpl -e 's/abc/ABC/g;'
    ABCde
  • 複数の置換を一気に。まずはsed。これは知らなかった。$ cat example.sed
    s/a/A/g
    s/b/B/g
    s/c/C/g
    $ echo "abcde" |  sed -f example.sed
    ABCde
    これをPerlで。コマンドラインだとこんな感じ。$ echo "abcde" | perl -wpl -e '
    > s/a/A/g;
    > s/b/B/g;
    > s/c/C/g;'
    ABCde
    スクリプトだと以下。$ cat example.pl
    #!/usr/bin/perl -wpl
    s/a/A/g;
    s/b/B/g;
    s/c/C/g;
    $ echo "abcde" | ./example.pl
    ABCde
  • 行を指定して置換。sedの場合。$ cat sample.txt
    This is sentence 1.
    This is sentence 2.
    This is sentence 3.
    $ sed '1s/sentence/REVISED_SENTENCE/g;' sample.txt
    This is REVISED_SENTENCE 1.
    This is sentence 2.
    This is sentence 3.
    Perlだと行番号を表す$.を使う。$ perl -wpl -e '$. == 1 and s/sentence/REVISED_SENTENCE/g;' sample.txt
    This is REVISED_SENTENCE 1.
    This is sentence 2.
    This is sentence 3.
  • -0digitを使って、段落単位、ファイル単位もできる。$ cat sample2.txt
    This is paragraph 1.
    And, this is a sentence for paragraph 1.
     
    This is paragraph 2.
    And, this is a sentence for paragraph 2.
     
    This is paragraph 3.
    And, this is a sentence for paragraph 3.
    $ perl -00 -wpl -e '$. == 1 and s/paragraph/PARAGRAPH/g;' sample2.txt
    This is PARAGRAPH 1.
    And, this is a sentence for PARAGRAPH 1.
     
    This is paragraph 2.
    And, this is a sentence for paragraph 2.
     
    This is paragraph 3.
    And, this is a sentence for paragraph 3.
     
  • 後方参照。sedとPerlだとマッチ部分のカッコのエスケープが逆なので注意。まずsed。$ echo "This is a sample sentence." | sed 's/^\(.*\) \(sentence\.\)$/\1 REVISED \2/g'
    This is a sample REVISED sentence.
    sedはカッコにエスケープをつけると正規表現の部分マッチ用のカッコとなる。次にPerl。$ echo "This is a sample sentence." | perl -wpl -e 's/^(.*) (sentence\.)$/$1 REVISED $2/g'
    This is a sample REVISED sentence.
    Perlの場合は逆にエスケープをつけない場合が正規表現のマッチ用カッコとなる。
  • 行番号で表示を指定。例として2行目以降を出力してみる。$ sed -n '2,$p' sample.txt
    This is sentence 2.
    This is sentence 3.
    Perlだとこんな感じ。$ perl -wnl -e '$. > 1 and print;' sample.txt
    This is sentence 2.
    This is sentence 3.
  • もちろん、さっきとおんなじように、-0digitを使えば、段落単位・ファイル単位とかも可能

sedで後方参照する時っていつもカッコのエスケープ忘れてハマるんだよね、苦笑。行番号の箇所なんかもキー入力はPerlのほうが少し多くなるけど、直感的。

[s21ht]梅田某所より
2008/10/28 21:24 posted by kunkichi

speed_test_umeda.jpg

おお、本領発揮。

[時間割:読書] 『READING HACKS!』
2008/10/28 02:14 posted by kunkichi

毎日読書を続けていて思うのはいつもこの2点。

  • もっと早く読みたい!→たくさん読める
  • もっと深く読みたい!→理解力が高まる
  • もっと早くたくさんアウトプットしたい!→アクセス数アップ(爆)

ということで、書店でもちらほら見かける読書本を数冊チョイスしたのですが、そのうちの1冊がこれ。

READING HACKS!―読書ハック! 超アウトプット生産のための「読む」技術と習慣
原尻 淳一
東洋経済新報社
売り上げランキング: 1114

先週まで『本を読む本』をずっと読んでたのですが、『READING HACKS!』が久々のHACK本ということで、『本を読む本』はちょっと休憩して、『READING HACKS!』を先に。読みやすさではこっちのほうが読みやすいし、サブタイトルに「趙アウトプット生産のため」とあったので、まさに今の僕のための本!(笑)ということで、一気に読み終えました。

基本的には、いつものHACK本と同じく、小さなHACKがたくさんまとめられてますが、気になったところだけピックアップ。僕の場合は、技術書が読書のメインなのですが、ビジネス書とは多少違う部分があるので技術書の場合のアプローチも併せて考えてみました。

  • 集中モードへの切り替えにハーブミスト買いました。とりあえずamazonで買ったのだけど、梅田ロフトでも売ってることを確認。ちなみに僕はラベンダー系の香りはずっと苦手だったのですがこれは大丈夫。
  • インプットとアウトプットは同時にやらない。これまでは勉強しながらメモがてらブログを書いていたけど、やっぱり理解力が足りない気がしていた。メモはメモ、アウトプットはアウトプットにちゃんと分けるように。
  • 音楽聞きながら、はモノによってはむしろ加速度を高めてくれる。ということで、僕の場合、クラシックは少し眠くなるので、ボーカルの入っていないJazzのインストもの、特に多少アップテンポなものをチョイス。
  • ホームライブラリー化に本棚を検討。部屋が狭くて本棚をおくと圧迫感が出るのが嫌だったのだけど、本が並んでる姿を見て雰囲気を出すのも重要かも。IKEAだと、BILLYのホワイトが安くて良さげ。
  • もう少し行きつけのカフェとかは開拓したい。会社帰りだと、丸ビル前のシアトルズ・ベスト、ちょっと足を伸ばして、肥後橋のスタバ(ここは2階が空いていて結構穴場)あたり。ただやっぱり梅田近辺なのでいつも混んでる。京橋近辺で静かでPC立ち上げて長居できそうなところを見つけたい。
  • 読書投資基準の70:20:10モデルを僕自身に照らし合わせてみると、サーバ系70、プログラミング系20、その他10って感じにすべきなのかな。ちょっとプログラミング系が多い最近だけど。一応、時間割的に通勤時の読書は技術書以外っていうのを意識してるのでOK。
  • 年間読書キャンペーンは、一つのプログラミング言語をきちんと学ぶには最低1年ぐらいは必要だと思うので、ちょうどよし。今年の年末までにはLinuxカーネルソースをなんとか読めるぐらいになりたい!
  • 生涯読書ランキング作ろう。ランキングは読書だけに限らず、選ぶ作業自体がかなり楽しい。モチベーションあがる。
  • 読書記録をきちんとつけて、自分の読書傾向を分析、自分が今読んでる本のレベルから特定の分野の理解度がどこまで進んでいるか?とか、逆に足りない範囲はどこか?とか、を把握するのは良いかも。メディアマーカーお試し中。
  • 目次読書→スキミング→特定の箇所だけピックアップして読む、この流れを忘れずに、要点の把握とスピードアップ。技術書の場合でもこれは使えるはず。伊藤直也さんトークセッションでもあったのだけど、「繰り返し」のスピードを上げて理解力を上げるほうにポイントを置きたい。
  • 目的意識は常に念頭に。技術書の場合はもちろんその技術の習得が目的なのだけど、その技術を使って何をするか?を常に考えるようにしないと。
  • 読書キット作成しました!100円ショップでほぼ揃います。個人的に失敗したのは、キットを入れる入れ物として布製・メッシュのやつを選んだのだけど、取り出すとき本の重みで形が崩れる。電車の中とかではちょっとつらい。ビニールの多少固めのものを選んだほうがベター。
  • アウトプットへのこだわりを持つ。文体とか情報の精度とか。
  • ホームグラウンドはやっぱり技術。常に理論から仮説をたてて実践するという日々の運用やトラブル対応の基本を読書の中にも持っておきたい。
  • アウトプットが大前提。

うん、小山さんの『STUDY HACKS!』に引き続き、今回も良書でした。『〜 HACKS!』系は読みやすい上に外れを感じないです。とりあえずアウトプットは常に念頭にある状態にはなっているので、もっとアウトプットのスピードとクオリティを上げることが個人的にはテーマかな。

[時間割:Perl]『ミニマルPerl』その6
2008/10/28 01:49 posted by kunkichi

火曜日は『Perl』の時間です。行をまたがる正規表現のところから。

  • 普通は . でニューライン(¥n)はとれないのだけど、シングルラインモードを使えば¥nもマッチ対象とすることができる。これを使って複数行にまたがるマッチングを行う。$ cat lines.txt
    abcde fghij
    klmno pqrst
    uvwxyz
    $ perl -00 -wnl -e '/\bfghij\b.*\bklmno\b/si and print $&;' lines.txt
    fghij
    klmno
  • ポイントは以下。
    • 入力レコードセパレータを-00とか-0777とか複数行読み込めるものにする。
    • マッチ修飾子にシングルラインモード(s)を有効にして、¥nがマッチするような正規表現を書く。*. とか。
  • いろいろ試してみる。BINDのqueryログから、問い合わせホスト名が2文字のTLDで終わっているものを参照。$ perl -wnl -e '/query: \S+\.[a-z][a-z] /i and print;' query.log27-Oct-2008 23:28:02.221 queries: client XXX.XXX.XXX.XXX#XXXXX 〜 query: atode.cc IN A +
    27-Oct-2008 23:54:14.192 queries: client XXX.XXX.XXX.XXX#XXXXX 〜 query: www.uniqlo.jp IN A +
    27-Oct-2008 23:59:02.339 queries: client XXX.XXX.XXX.XXX#XXXXX 〜 query: www.oreilly.co.jp IN A +
    さらに.jpドメインのものを除外する。$ perl -wnl -e '/query: \S+\.[a-z][a-z] /i and ! /query: \S+\.jp /i and print;' query.log27-Oct-2008 23:28:02.221 queries: client XXX.XXX.XXX.XXX#XXXXX 〜 query: atode.cc IN A +
  • String::Approxを使ってファジーマッチングも可能。# cat fuzzy_match
    ----------
    #!/usr/bin/perl -s -wnl
    use String::Approx 'amatch';
    amatch $pattern, [ "i", "20%" ] and print;
    ----------
    echo "yafoo" | ./fuzzymatch -pattern='yahoo'
    yafoo
  • スクレイピングの例。www.php.netの右上にあるStableのバージョンのうち、5.X系のバージョンを取得する。$ lwp-request -o text www.php.net | perl -wnl -e '/Stable/ and /5\.\d\.\d/ and print $&;'
    5.2.6

以下、grep処理のまとめ

grepコマンド Perlでの書き方
grep ‘〜’ perl -wnl -e ‘/〜/ and print;’
grep -v ‘〜’ perl -wnl -e ‘/〜/ or print;’
grep -i ‘〜’ perl -wnl -e ‘/〜/i and print;’
grep -l ‘〜’ perl -wnl -e ‘/〜/ and print $ARGV and close ARGV;’
fgrep ‘〜’ perl -wnl -e ‘/¥Q〜¥E/ and print;’

シチュエーションによってはgrepのほうが簡単な場合もあるけど、まあそこはケースバイケースで。ちょくちょく使って慣れていこう。。

[時間割:C言語]『はじめてのC言語完全入門』その8
2008/10/25 22:49 posted by kunkichi

今週の頭は少しサボっちゃいましたが、気を取り直して。サボりの元凶となったのは Touch Diamond を買ったから(笑)ですが、遊びのために買ったんじゃない、ということを証明するために早速、金曜日の会社帰りに外で勉強しました。やっぱり外ははかどるな〜、3章一気に進んじゃったし。

ということで、木・金のアップです。まずは『C言語』の方から。

はじめてのC言語 完全入門 (標準プログラマーズライブラリ)
塚越 一雄
技術評論社
売り上げランキング: 420963


関数

  • Cの場合、関数の定義には、以下が必要。
    • 関数名
    • 関数の型。返り値の型を決める必要がある。
    • 引数。
    • 関数値。いわゆる、返り値。

    なんといっても、「型」が必要ってところが、PerlとかPHPとかとの最大の違い。

  • 返り値がない場合は、型にvoid を指定する。でもってreturnは値を指定しないか、returnそのものを省略できる。
  • ただし、void型関数の途中で終了する場合は、returnを使う。
  • 引数なしの場合は、voidを使う。voidを使わずに()だけで書いた場合は、引数がないのではなく、コンパイラが引数のチェックをしない、という意味になるので注意。
  • 関数を定義する場所は、
    • 関数が呼び出される場所よりも前に書く(Pascal方式)。シェルスクリプトはこっち。
    • 関数が呼び出される場所よりも後に書く(C方式)。ただしこの場合は、呼び出される前にプロトタイプ宣言が必要。
  • プロトタイプ宣言は、関数の使い方のチェックを行うためのもの、と言える。
  • static変数とauto変数の違い。
    • auto変数は、関数呼び出し時に初期化され、関数終了時に消滅する。#include <stdio.h>
       
      void auto_hensuu();
       
      int main()
      {
        auto_hensuu();
        printf("----------\n");
        auto_hensuu();
        return 0;
      }
       
      void auto_hensuu()
      {
        int i,num = 0;
        for(i=0; i<10; i++){
          printf("auto関数 %2d 回目: num  = %d\n", i +1 , num );
          num += 10;
        }
        return;
      }
      実行結果:$  ./kansuu
      auto関数  1 回目: num  = 0
      auto関数  2 回目: num  = 10
      auto関数  3 回目: num  = 20
      auto関数  4 回目: num  = 30
      auto関数  5 回目: num  = 40
      auto関数  6 回目: num  = 50
      auto関数  7 回目: num  = 60
      auto関数  8 回目: num  = 70
      auto関数  9 回目: num  = 80
      auto関数 10 回目: num  = 90
      ----------
      auto関数  1 回目: num  = 0
      auto関数  2 回目: num  = 10
      auto関数  3 回目: num  = 20
      auto関数  4 回目: num  = 30
      auto関数  5 回目: num  = 40
      auto関数  6 回目: num  = 50
      auto関数  7 回目: num  = 60
      auto関数  8 回目: num  = 70
      auto関数  9 回目: num  = 80
      auto関数 10 回目: num  = 90
      2回目の関数呼び出し時に変数が初期化されている。
    • static変数は、プログラム実行時に初期化され、プログラム終了時に消滅する。#include <stdio.h>
       
      void static_hensuu();
       
      int main()
      {
        static_hensuu();
        printf("----------\n");
        static_hensuu();
        return 0;
      }
       
      void static_hensuu()
      {
        int i = 0;
        static int num = 0;
        for(i=0; i<10; i++){
          printf("static関数 %2d 回目: num  = %d\n", i +1 , num );
          num += 10;
        }
        return;
      }
      実行結果:$ ./kansuu2
      static関数  1 回目: num  = 0
      static関数  2 回目: num  = 10
      static関数  3 回目: num  = 20
      static関数  4 回目: num  = 30
      static関数  5 回目: num  = 40
      static関数  6 回目: num  = 50
      static関数  7 回目: num  = 60
      static関数  8 回目: num  = 70
      static関数  9 回目: num  = 80
      static関数 10 回目: num  = 90
      ----------
      static関数  1 回目: num  = 100
      static関数  2 回目: num  = 110
      static関数  3 回目: num  = 120
      static関数  4 回目: num  = 130
      static関数  5 回目: num  = 140
      static関数  6 回目: num  = 150
      static関数  7 回目: num  = 160
      static関数  8 回目: num  = 170
      static関数  9 回目: num  = 180
      static関数 10 回目: num  = 190
      2回目の呼び出し時に1回目の処理終了時の変数をそのまま引き続き使用している。
  • 値を返さないvoid型関数は値を取るような処理では使えない。結果を代入するとか、結果を出力するとか(もちろん関数内で出力することはできる)。逆に値を返す関数は、値を取らない処理でも使える。
  • べき乗を計算するpow()を使う場合は、math.hをインクルードする。
  • 引数を取る関数は、仮引数を定義しなければいけない。その場合、仮引数の型も合わせて定義する。
  • プロトタイプ宣言している場合は、そちらにも引数をちゃんと指定すること。

スコープ

  • 関数内の変数は関数内にのみ限定される(ローカル変数)。
  • 実際には「ブロック」内、つまり{}で囲まれた範囲内に限定されているのがローカル変数。
  • 関数の外側の変数は、関数から見た場合にはグローバル変数となり、参照可能。
  • 変数名もブロック内に限定されるので、他の関数内で同じ変数名が使用されていても衝突しない。
  • ただし、グローバルな変数名と同じ名前にした場合、関数内ではローカル変数が優先される。
  • グローバル変数はファイルスコープ。

配列

  • 配列にも型の概念がある。すなわち、同じ型のデータしか入れれない。異なる型のデータを入れるのは構造体。
  • 配列は、基本の型とは異なるユーザ定義型の一つ。
  • 配列を宣言するには、型・配列名・サイズ(要素数)をあらかじめ定義する。int ary[10]
  • 初期値を与えることもできる。int ary[] = { 1, 2, 3 };この場合はサイズの指定は不要(自動的に初期値の個数がサイズとなる)
  • 配列の要素へのアクセスは、インデックスを使う。x = ary[0];
  • 配列全体のメモリ量を求めるには 配列に対して sizeof を使う。sum = sizeof ary;
  • 配列要素の単体メモリ量を求めるには 配列のインデックス0 に対して sizeof を使う。each = sizeof ary[0]
  • つまり、全体メモリ量を単体メモリで割ると、配列の要素数を求めることができる。num = sizeof ary / sizeof ary[0];forループの上限値等に設定する場合はこれをつかうとよろし。
  • forループの脱出にもbreakが使える。
  • ループの脱出にはbreakを使う。
  • 配列はあらかじめサイズを指定しておかないといけないため、途中でサイズが大きくなった場合に対応できない。こういう場合は動的メモリが必要となる。

ふぅ、たくさん進んだ分、アウトプットも多くなってしまいましたが、これで教科書の残り3分の1まで来ました。やっと終わりが見えてきたのでがんばります。次はいよいよ「ポインタ」です!

このページの先頭へ