Open Source WEB



2004-10-29 [wget] ディレクトリのカット

wget を使って、ファイルをもってくるとき、ホスト名およびファイルパスが そのまま、手元のディレクトリにできてしまう。たとえば、

% wget -r -L -N http://mitpress.mit.edu/sicp/full-text/book/book.html

とやると、手元のディレクトリには mitpress.mit.edu/sicp/full-text/book という具合にディレクトリが深くできてしまう。カレントディレクトリに book.html など、データが欲しいときには、-nH オプションと --cut-dirs=3 を組み合せて

% wget -r -L -N -nH --cut-dirs=3 http://mitpress.mit.edu/sicp/full-text/book/book.html

とするとよい。


Name:
Comment:

There is no comment.


2004-10-28 [zsh] グローバルエイリアス

「なんのために、zsh つことんじゃぁ!」シリーズ 第2弾 (^-^;)

alias -g A='|awk'
alias -g G='|grep'
alias -g GV='|grep -v'
alias -g L='|TERM=vt100 lv'
alias -g S='|sed'
alias -g W='|wc'

とかやっとくと、

% cat access.log | awk '{if($9=="404")print}' | grep -v favicon.ico | TERM=vt100 lv

% cat access.log A '{if($9=="404")print}' GV favicon.ico L

とできる。


Name:
Comment:

There is no comment.


2004-10-27 [perl] ファイル名の変更

また、「知らなんだorz」シリーズ(いつ、シリーズ化したんや?)

rename なんてコマンドがあった。

% rename 's/\.orig$//' *.orig

ファイル名の末尾の .orig を除去

% rename 'print "$_: "; s/soko/goyo/ if <STDIN> =~ /^y/i' *

対話的に確認しつつ、file名の soko という文字列を goyo に変更する、 なんてことまでできる。

内容は perl で書かれていた。Larry Wall のコードだった。


Name:
Comment:
s: (Wed Oct 27 19:17:15 2004 )
zshで
for i in *.orig; mv $i ${i%.orig}
とかも便利ですね
novice: (Thu Oct 28 15:04:37 2004 )
rename .orig '' *.orig
で末尾の .orig は消えるみたい。(bash)
'' は "" でもOKみたい。


2004-10-26 [zsh] コマンドの入力履歴の検索

うぅ。知らんかった。「なんのために、zsh つことんじゃぁ!」

C-r

コマンドの入力履歴をインクリメンタルサーチしてくれる。便利杉。


Name:
Comment:

There is no comment.


2004-10-25 [Emacs] 括弧単位の移動

Emacs にはS式単位でカーソルを移動するコマンドがある。

  • forward-sexp
  • backward-sexp

で、このコマンドは通常それぞれ

M-C-f

M-C-b

とに割り当てられている。

(define (comb n k)
  (cond ((= k 0) 1)
        ((= k n) 1)
        (else (+ (comb (- n 1) k) (comb (- n 1) (- k 1))))))

のような式を書いておいて、C-f や C-b それに M-C-f や M-C-b を試すとよい。 さらに、LISP や Scheme のプログラムだけではなく、括弧であればその種類を とわず、移動します。

z = [ y + { x * (3 +4)} - 7]

とか、

彼は「そもそも、『再帰』の方が『ループ』よりも単純な概念だ」言いはった。

とか書いておいて、移動を試すと良くわかる。


Name:
Comment:

There is no comment.


2004-10-22 たらいまわし関数

複雑な(原始帰納関数ではない)再帰関数。むかし、むかし、その昔には 言語処理系のベンチマークに使われたとか、使われないとか、それ以外 なんの使い道もない伝説の関数。

初めての人のためのLISP』より、Common LISP のコード(関数名をtaraiに変更)。

(defun tarai (x y z)
  (cond ((> x y) (tarai (tarai (1- x) y z)
                        (tarai (1- y) z x)
                        (tarai (1- z) x y)))
        (t y)))

C言語による最新アルゴリズム辞典』より、Cのコード

int tarai(int x, int y, int z)
{
    if (x <= y) return y;
    return tarai(tarai(x - 1, y, z),
                 tarai(y - 1, z, x),
                 tarai(z - 1, x, y));
}

この関数はとてつもなく、重い関数です。ためしに tarai(16,8,0) あたりを 計算させてみてください。きっと待てませんから。

そこで、じゃじゃじゃん。Haskellのコード

tarai x y z | x <= y    = y
            | otherwise = tarai (tarai (x - 1) y z)
                                (tarai (y - 1) z x)
                                (tarai (z - 1) x z)

Haskell で書いた tarai は Hugs インタープリタで動作させても、 他のスクリプト言語、Perl、Ruby、Python、Gauche で書いたものよりも 圧倒的に(というか比べるのさえばかばかしいほど)速いです。 それどころか、Java や C/C++ で書いたてコンパイル したコードよりも Hugs インタープリタで実行する Haskell のコードの 方が速いです。

まっ。「だから何?」ですが。。。


Name:
Comment:

There is no comment.


2004-10-21 [Emacs] 検索結果一覧

バッファ全体を検索して、マッチした行を一覧させるには、

M-x occur

とやって、正規表現の入力すると別ウィンドウでマッチした行を一覧表示してくれる。 表示された特定の行へマウスカーソルをもっていって、中ボタンを押すと、検索を したバッファの当該位置に飛んでくれる。


Name:
Comment:
s: (Thu Oct 21 11:10:16 2004 )
M-x re-builder
も便利ですね。
正規表現を入力するとマッチする箇所がリアルタイムにハイライトされます。


2004-10-20 [Emacs] リージョンの色づけ

操作の範囲を確認するのにリージョンの色づけが欲しいことがあります。 これを有効にするには、

M-x transient-mark-mode

とします。このコマンドはトグルになっているので、色づけが、欝陶しいときは もう一度、

M-x transient-mark-mode

とすれば、色付が無効になります。 この切り替えをキー操作に割当るなら、.emacs にたとえば、

(global-set-key "\C-c\C-t" 'transient-mark-mode)

と書いておけば C-cC-t でリージョンの色づけをトグルすることができます。


Name:
Comment:

There is no comment.


2004-10-19 スクロールバーの幅

ノートPCなどの解像度の低いディスプレイを使っていると、Window の飾りを できるだけ小さくしたいことがある。スクロールバーの幅もそのひとつ。

Zt日記に関連する 記述があったので試してみた。

私の環境で $HOME/.gtkrc-2.0 (なかったので新規作成) に

style "my-scrollbar"
{
  GtkRange::slider_width = 7
  GtkRange::stepper_size = 7
}
 
class "GtkScrollbar" style "my-scrollbar"

を書いたら、firefox のスクロールバーが細くなった。Happy!


Name:
Comment:

There is no comment.


2004-10-18 [XML] コメント

XML のコメントは、<!-- ではじめて、--> で終るように書く。 <!-- と --> あいだに -- を入れてはいけない。 (何故そのような仕様にしてるのか知らない。ご存知でしたら教えてください。)

注意しなければいけないのは、複数行にまたがって書かれている要素全体を コメントアウトするときに、その要素のなかに -- が入っていないことを 確認することです。コメントアウトしたい要素の中に -- が含まれているときに これを &#45;&#45; とかに変換する必要があるかもしれません。


Name:
Comment:
みやざき: (Mon Oct 25 19:54:53 2004 )
--をきちんと対にして書く人が少なかったし、解釈する方も面倒だから --は前後 2回しか使っちゃだめってことにしたんじゃないでしょうかね?


2004-10-15 [Emacs] コメント

リージョン単位で、コメントにしたり、コメントを解除したりする

M-x comment-region

これで、リージョンがコメントになる。

M-x uncomment-region

これで、リージョンのコメントが解除になる。 ただし、コメント行を含むリージョンを comment-region でコメントにした場合、 uncomment-region で元にもどらない(元々コメント行だったところが、 コメント行にならない)ことがあるので、ちょっとした注意が必要。


Name:
Comment:

There is no comment.


2004-10-14 [Emacs] ミニバッファの履歴

ミニバッファ中で、

M-p

とか

M-n

とか。

Emacs には常識の範囲なんだろうけど、使い方を知らないものが 山ほどあるねぇ。(って、おめえだけだよ > 儂)

「計算機でできることを手でやらない」を追及せねば。。。


Name:
Comment:

There is no comment.


2004-10-13 [Emacs] ChangeLogの編集

ChangeLog ファイルに記録を残すための Emacs コマンド

M-x add-change-log-entry-other-window

これは、C-x 4 a のキー操作に割り当てられている。


Name:
Comment:

There is no comment.


2004-10-12 素因数分解

指定した数の素因数分解を求めるスクリプト

#!/usr/local/bin/runhugs +l
\begin{code}
module Main where
import System
import IO
import Char
main :: IO ()
main = do argv <- getArgs
          case argv of
            [a] -> if and (map isDigit a)
                   then putStrLn (show $ factors (read a))
                   else usage
            _   -> usage
usage :: IO ()
usage = hPutStrLn stderr "Usage: factors number"

factors n 
  = factorize [] (prms n (2:[3,5..])) n
    where
      prms n ps = takeWhile (ceiling (sqrt (fromInteger (n+1))) > ) ps
      factorize rs [] n         = reverse (n:rs)
      factorize rs pps@(p:ps) n = case n `divMod` p of
                                    (1,0) -> reverse (n:rs)
                                    (m,0) -> factorize (p:rs) (prms m pps) m
                                    _     -> factorize rs ps n
\end{code}

実行例

% ./factors 123456789
[3,3,3607,3803]
% ./factors 2147483647
[2147483647]

2147483647 = 2^31-1 (メルセンヌ素数)


Name:
Comment:

There is no comment.


2004-10-08 zsh バックグラウンドジョブのデーモン化(?)

バックグラウンドで走らせたジョブを、あとになって、起動したシェルと 切離したいときがある。zsh には、そんなとき用に disown という 組み込みコマンドがある。

% hoge --hero &
[1] 18379

のように起動しておいて、ジョブテーブルを見ると

% jobs
[1]  + running    hoge --hero

たしかに、バックグラウンドで動作している。これを

% disown %1

とやると、ジョブテーブルから削除されるが、プロセスIDでチェックすると

% jobs
% ps 18379
  PID TTY      STAT     TIME COMMAND
18379 pty/s1   S        0:00 hoge --hero

たしかに、実行され続けていることがわかる。


Name:
Comment:

There is no comment.


2004-10-07 素数表

指定した数以下の素数の一覧を得るスクリプト

#!/usr/local/bin/runhugs +l
\begin{code}
module Main where
import System
import IO
main :: IO ()
main = do argv <- getArgs
          case argv of
            [a] -> mapM_ print $ takeWhile (read a >=) primes
            _   -> hPutStrLn stderr "Usage: primes max"
primes :: [Int]
primes = map head $ iterate sieve [2..]
sieve :: [Int] -> [Int]
sieve (p:xs) = [ x | x <- xs, x `mod` p /= 0 ]
\end{code}

実行例

% ./primes 20
2
3
5
7
11
13
17
19


Name:
Comment:

There is no comment.


2004-10-06 zeller の公式

日付から曜日を求めるには、cal を呼べばよいのだけれど、 自前で計算するなら、 ツェラーの公式というのがある。

Haskell スクリプトにするなら、

#!/usr/local/bin/runhugs +l
\begin{code}
module Main where
import System
import IO
main :: IO ()
main = do argv <- getArgs
          case argv of
            [y,m,d] -> hPutStrLn stdout $ zeller (read y) (read m) (read d)
            _       -> hPutStrLn stderr "Usage: zeller year month day"
zeller :: Int -> Int -> Int -> String
zeller y m d
 = if m < 3
      then zeller (y-1) (12+m) d
      else ["日","月","火","水","木","金","土"] !! (z `mod` 7)
      where
         (p,q) = divMod y 100
         z = sum [ 21 * p `div` 4, 5 * q `div` 4, 26 * (m+1) `div` 10, d - 1]
\end{code}

これを、zeller というファイル名でセーブして、実行パーミッションを 立てると、実行できる(/usr/local/bin/runhugs はインストール済みとする)。

% ./zeller 2004 10 6
水

runhugs は Hugs98 の配布物の一部。 インストールは簡単。


Name:
Comment:

There is no comment.


2004-10-05 stty 端末の設定を見る

% stty -a

で現在の設定を表示することができる

% stty -a
speed 9600 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

intr = ^C とあるのは、Ctrl-c とやると、SIGINTが、quit = ^\ とあるのは Ctrl-\ とやると SIGQUIT が発行されることを示している。 ループしてそうなプログラムを走らせてしまったとき、core を吐かせて、 強制終了させるためには、Ctrl-\ とやればいいということがわかる。


Name:
Comment:

There is no comment.


2004-10-04 Email アドレスに対応する正規表現

RFC2822 にある正しいEmailアドレスの validation を正規表現で行うのは 原理的には無理(正則文法では、すべての正しいEmailアドレスを生成は不可能) なので、制限つきだが、例えば、

^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$

のようなものがある。これは、Regular Expression Libraryという サイトでみつけたもの。

正規表現は便利だが、正しく書くのはなかなか難しく、 Emailアドレスのように厳密には正規表現 を使うのは無理なものがあることにも注意しなければならない。

厳密なEmailアドレスのValidatorを作るなら、RFCにある拡張BNF記述を処理できる パーサジェネレータをつかって、パーサを作成することになる。

正規表現については書籍では、 「詳説正規表現 第2版」がおすすめ。


Name:
Comment:

There is no comment.


2004-10-01 population count 1ビットの数え上げ

「ハッカーのたのしみ」より、もうひとつ、

2004-09-17の一番右にある on ビットを off にする演算を使う方法

int pop (unsigned x) {
  int n;
  n = 0;
  while (x != 0) {
     n = n + 1;
     x = x & (x - 1);
  }
  return n;
}

Hacker's Delight には、ほかにもびっくりするような方法もあります。


Name:
Comment:

There is no comment.


このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us