I ♥ WordPress

[メモ] 10進数 ←→ 16進数の計算
2008/11/24 14:47 posted by kunkichi

メモその2。

例1:16進数 A5 を 10進数に。

まず、10進数と16進数の対応を確認。

10進数 16進数
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 A
11 B
12 C
13 D
14 E
15 F

各桁数-1を16の乗数として、それに16進数が対応する10進数をかけたものを最後に足す。

A(10) × 161
5(5) × 160

⇒ 165

例2:10進数 251 を 16進数に。

10進数の数字を16で割っていき、その商が0になるまで繰り返す。各あまりを下から順に並べて、16進数で置き換える。

251 ÷ 16 = 15 あまり 11 (B)
15 ÷ 16 = 0 あまり 15 (F)

⇒ FB

[メモ] 10進数 ←→ 2進数の計算
2008/11/24 14:23 posted by kunkichi

メモ。

例1:10進数 15 を 2進数に。

10進数の数字を2で割っていき、その商が0になるまで繰り返す。各あまりを下から順に並べると10進数になる。

15 ÷ 2 = 7 あまり 1
7 ÷ 2 = 3 あまり 1
3 ÷ 2 = 1 あまり 1
1 ÷ 2 = 0 あまり 1

⇒ 1111

例2:10進数 32 を 2進数に。

32 ÷ 2 = 16 あまり 0
16 ÷ 2 = 8 あまり 0
8 ÷ 2 = 4 あまり 0
4 ÷ 2 = 2 あまり 0
2 ÷ 2 = 1 あまり 0
1 ÷ 2 = 0 あまり 1

⇒ 100000

例3:2進数 10011 を 10進数に。

各桁数-1を2の乗数として、それに2進数をかけたものを最後に足す。

1×24 = 16
0×23 = 0
0×22 = 0
1×21 = 2
1×20 = 1

⇒ 19

[時間割:C言語]『はじめてのC言語完全入門』その11
2008/11/21 22:59 posted by kunkichi

いかんいかん、XBOX360の「FIFA09」が出たせいでサボりまくり、、、
気分を取り直してがんばります。金曜日は「C言語」。今日は文字列です。

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


  • Cには文字列型は存在しない。文字列は文字型の配列を使う。なぜなら可変長だから。
  • 文字列の初期化は以下の数パターン。
    • 文字単位で初期化。#include <stdio.h>
       
      int main()
      {
        char s[5];
       
        s[0] = 'a';
        s[1] = 'b';
        s[2] = 'c';
        s[3] = '\0';
       
        printf("%s\n", s);
       
        return 0;
      }
      ポイントをいくつか。
      • 宣言するときにサイズもあわせて宣言する。サイズは代入したい文字数に1を足しておく。
      • 1を足したのは最後に文字列の終わりを示すEOS(End Of String)の分。EOSにはNULL文字を使う。文字列の場合は\0。
      • printfで出力する場合は%sで配列名を指定する。
    • {}をつかったやり方#include <stdio.h>
       
      int main()
      {
        char s[] = {'a', 'b', 'c'};;
       
        printf("%s\n", s);
       
        return 0;
      }
      この場合はサイズの宣言は不要。よしなにやってくれる。
    • 文字列リテラルで。#include <stdio.h>
       
      int main()
      {
        char s[] = "abc";
       
        printf("%s\n", s);
       
        return 0;
      }
      一番普通。
  • {}を使った場合や文字列リテラルで初期化した場合でもサイズの指定は可能。ただし、EOSの分を足すことを忘れないこと。
  • 同じ文字だけの文字列で初期化する場合は、string.hのmemset関数を使う。#include <stdio.h>
    #include <string.h>
     
    int main()
    {
      char s[4];
     
      memset(s,'a',3);  /* 1: 代入する配列、2:文字、3:文字数 */
      s[3] = '\0';          /* 最後にEOSを代入。面倒、、、 */
     
      printf("%s\n", s);
     
      return 0;
    }
  • 文字列宣言後に文字列リテラルで代入することはできない。その場合はベタに文字配列で要素ごとに代入するか、strcpyを使う(これはまだ先)。文字配列の場合はEOSを最後に代入することを忘れないこと。
  • サイズを超えた場合でも、サイズに見たない場合でも、コンパイラはエラー等を返さないので注意。特に超えた場合は、、、

うーん、やっぱり文字列の扱いは面倒だなぁ、特にサイズを意識しないといけないってのは厳しい。十分に気をつけるようにして次へ進みましょう。次回は「ファイル入出力」。やっと実際のプログラミングらしくなってきました。

[時間割:読書] 『ちょっとした勉強のコツ』
2008/11/21 01:48 posted by kunkichi

外山先生の本を読むのは大学入試以来だったりしますw

読書論、的な本を探してたら、とあるブログで紹介されていた『「読み」の整理学』がなかなか面白かったので、続けてこれをチョイス。

ちょっとした勉強のコツ (PHP文庫 と 7-13)
外山 滋比古
PHP研究所
売り上げランキング: 15604

もう10年近く前の本だけど、今読むととてもLifehacks的。紹介されている内容も実践的で手軽に試せそうなものが多くて、でもとても読みやすい、ただちょっと繰り返しが多いかな。『「読み」の整理学』とちょっとかぶってるところもあったりするし。なのでザーッと目を通す程度で読むのが一番いい気がします。でも豊富な例証がさすが外山先生という感じです。

早速気になったところだけピックアップ。

  • 文字通りのハングリーな状態が頭を一番うまく使える。
    →朝の朝食前が心身ともにベスト。朝食と昼食をブランチにして、午前中にがんばるのを試してみよう。
  • ハングリーな状態は時間にも使える。時間があるよりもないほうが集中力が高まる。
    →時間割でメリハリをつけるのは正解。
  • 正しい姿勢が知的活力に影響する。例えば「立って」勉強する。
    →バランスボールとかよいかも。
  • 多少の不都合な状態のほうがより頭が動く。
    →静かな状態よりも多少BGMがあるほうが刺激になる
  • 競い合う友人を持つことで、より効果が上がる。
  • 集中力の持続は訓練することでより向上する。
    →時間割の1単位を少しずつ伸ばしていこう。
  • 読むだけでなく、書くことでより理解力を高める
    →アウトプット重要!
  • 頭を使うことに、付帯条件を付けることで、より理解力が深まる。
    →正しい姿勢、ほどよい暗さ、かすかなBGM
  • 考えるときは頭を冷やすほうがよい。
    →冷却シートとかよいかも。
  • 人が集まる場合は違うタイプの人が集まる方が刺激的。
  • 一つのことに集中しているときこそ、予想外の事実やアイデアに出会うことがある。セレンディピティ。
  • その日のやるべきことを、生活時間割として朝一番に考える。
  • 劣等感やコンプレックスをモチベーションに。ライバルは強ければ強いほどそのモチベーションが高まる。
    →目標は高く!
  • その日のやるべきことを、生活時間割として朝一番に考える。
  • 勉強だけではなく、普段から頭の体操を意識する。→フェルミ推定の問題集とかいい気がするなー。

文庫本なのですぐに読めちゃうし安いんでサラッと読みたい場合はおすすめです。

読書論に限ると↓もおすすめ。

「読み」の整理学 (ちくま文庫 と 1-3)
外山 滋比古
筑摩書房
売り上げランキング: 64833

[時間割: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のほうが少し多くなるけど、直感的。

このページの先頭へ