Subscribe to RSS Subscribe to Comments Blog of Roy Chan

Blog of Roy Chan

使用 vim 編輯 web textarea (Firefox or Kazehakase)

用了 vi/vim 十多年,其他 text editor 對我來說確實很麻煩。大部份事用 vi/vim 做都有說不出的爽!!! 就算多年前因工作需要在 windows 寫程式寫,也懶得用 UltraEdit 等,抓個 vim windows 爽很多。近年,經常要在網頁上的 textarea 打一大篇文章,結果還是受不了,很多時需要在 copy&paste 到 vim 執行仔細的編輯。簡潔的按鍵自然是我喜用 vi/vim 的主要理由,regular expression 更是我編輯時不缺的利器。

幾年來,我花了不少工夫企圖把 regular expression 或 vi/vim 式的編輯引入 web,包括寫了些 bookmarklet 等,但始終和 vi/vim 差很遠。嘗試過幾個令 Firefox 使用 external editor 的 extension, 不過都不太有效。近兩年前,找到了 It’s All Text,終於把我這個難題解決了。

It’s All Text 這個 Firefox extension 安裝後,會在每個 textarea box 的右下角浮現一個 “edit” 小按鈕,按下就會把 textarea 的內容送去指定的 text editor 進行編輯,絕對是 vi/vim 的必裝 extension。

然而,這年來因為安全問題,我經常會同時使用多個 browser,用不同 browser 執行不同安全級別的 web apps。(都是 ajax 惹的禍)。Prism, Epiphany, Kazehakase,甚至 Opera 都會常用來代替 Firefox 執些較低 reliability 的 web site/apps (Prism 一般用來跑重要的 webapp 如 gmail 和 online-banking),Noscript extension 則用來限制不明網站的 javascript。不過用其他 browser 時,就少了 It’s All Text 用 external editor 的爽便。早期才發現用了半年的 Kazehakase 其實內建使用 external editor 的功能,多了個可以便利使用 browser。

在 Kazehakase 設定使用 gvim 很簡單,首先 UI Level 要設定為 Expert (View -> UI Level -> Expert),在 Edit -> Preference 中的 External Program,設定 Editor command 為:

gvim -f %s

就搞定了。 (-f 選項是避免 gvim 自動 fork 入背景工作,令 Kazehakaze 不知 gvim 完成編輯)

往後在要編輯的 textarea 按右鼠鍵在選單選 Launch Editor 就可以了。(當然是經謹關閉了 gvim 才好 submit web form)


Share It: [del.icio.us] [Technorati] [Google Bookmark] [Yahoo MyWeb] [Furl]


Tr - TRanslate characters

以下早八年前為PCWeekly HKLUG專欄寫的文章:

tr 是 Unix/Linux 一個很普遍的小工具,其功能也很簡單,主要把一組字母 map 成另一組字元。舉個例,請在打以下的指令:

 tr vms wnt

打了後請亂打堆字再按 [Enter] ,你會發覺 tr 會重覆顯示你所打的字,但「v」會變成了「w」,「m」變成了「n」,「s」則變成了「t」。要結束這個遊戲可以開個新行打 Ctrl-D 再按 [Enter] 。好了,相信閣下現在應該知到了 tr 的作用是什麼了。 tr 最常會被用作轉換大小階,看過以上的例題,閣下或者以為要打:

 tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ

這長長的指令。事實上只要用「tr a-z A-Z」就夠了。

簡簡單單一個程式,配合 Unix 上其他工具就有很多妙用。如閣下要把一目錄上所有檔案名稱轉成大寫,以可以在 bash/ksh/sh 用以下指令:

 for f in *
 do
   mv $f `echo $f | tr a-z A-Z`
 done

要把 vi 上把某行全部轉成小寫,可以在 vi 的編輯模式打「!!tr A-Z a-z」,一個段落則可以打 「!}tr A-Z a-z」。要轉整個檔案可以打「:%!tr A-Z a-z」。

有沒有發覺原本在 DOS/WIN 的文字檔放到 Unix/Linux 上看,每行都多了個「^M」。這是因為 Unix 、 DOS 及 Mac 等的文字檔格式都有所分別。 Unix 習慣每行用一個 Linefeed (ASCII 10) 分格, Mac 用一個 Carrier Return (ASCII 13) ,而 DOS 則要用一個 Carrier Return 跟一個 Linefeed 來分格,檔尾還要加個 Ctrl-Z (ASCII 26) 。要把 DOS 或 Mac 的文字檔轉成 Unix/Linux 格式最簡單可以利用 tr 。

  • Mac 轉 Unix/Linux - tr \\015 \\012 <mac.txt >unix.txt
  • Unix/Linux 轉 Mac - tr \\012 \\015 <unix.txt >mac.txt
  • DOS/Win 轉 Unix/Linux - tr -d \\015\\032 <dos.txt >unix.txt

012, 015 和 032 分別是 10, 13 和 26 的八進位。參數「-d」則叫 tr 把輸入檔中所有包括在字元組中的字元刪掉。


Share It: [del.icio.us] [Technorati] [Google Bookmark] [Yahoo MyWeb] [Furl]


Unix的歷史

這是我十多年前為TCL BBS Unix板寫的一篇關於Unix歷史的文章。事實上我只寫到三份之一就停了,不過這幾年來也偶然看到別人曾引用過這文章。近日我的舊個人網站要停了,所以把舊文貼上來作保存。

Multics 的失敗

要談 Unix 的歷史,一定要回溯到 1965-68 年美國電話及電報公司 (American Telephone and Telegraph Inc., AT&T) 、 通用電器公司 (General Electrics, G.E.) 及麻省理工學院 (Massachusetts Institute of Technology, MIT) 的 Multics (MULTiplexed Information and Computing Service) 計劃。

在那時期,大部份電腦都是採用批次處理 (Batch Processing) 方式。為了顯示多用途 (general-purpose) 及多用戶 (multiuser) 的分時系統 (timesharing system) 是可行的,MIT 以在試驗 CTSS (Compatible Time-Sharing System) 當中所得的研究成果取得了 G.E 的同意合作為 G.E. 的大型電腦 GE-635 開發一套全新的分時作業系統 - Multics 。

由於 Multics 有不少設計在當時是頗新穎具富創意的,因此吸引了不少研究機構的註意。而其中那時仍和 AT&T 同一家的貝爾實驗室 (Bell Libraries, Bell Labs) 更在六十年代末曾正式參於過 Multics 計劃,那時剛由加州柏克萊大學 (University of California at Berkeley, UCB) 去到 Bell Labs 的 Ken Thompson 就是 Multics 研究小組的一員。

不過 Multics 的發展進度很慢,原本預算兩年有成果但過了很久仍沒有多大進展。到了 1969 年, Bell Labs 終於決定放棄,退出了 Multics 計劃。 Bell Labs 的 Dennis Ritchie (K&R 的 R) 曾描述當時 Bell Labs 由管理層到研究員都認為 Multics 的開發是太遲及太貴了。

Multics 自 Bell Labs 退出後 , 仍有繼續發展。 Honeywell 在 1972 年購入了 G.E. 的電腦部門後更把 Multics 進出商業市場,但始終不算太成功。在 Multics 比較流行的八十年代,約有 75 至 100 台每台價值數百萬美元的大型電腦跑 Multics 。 1977 年, MIT 也退出 Multics 的發展工作。後來 Honeywell 在八十年代中期把其電腦上的事業賣給 Bull 後,Multics 的發展亦終於在 1988 年打上一個句號。

『角落中乏人問津的 PDP-7 』(”little-used PDP-7 in a corner”)

然而,Thompson 曾在 Multics 計劃當中為 GE-635 寫了個叫做「太空旅行」(Space Travel) 的遊戲程式。這個程式模擬 了一個太空船和太陽系的環境。 Bell Labs 放棄 Multics 後, Thompson 打算找另一台機器把「太空旅行」移植 (port) 過去,於是便和 Ritchie 向 Bell Labs 提議買一台電腦以便他們建立一台自己的交談式、多用戶、分時系統,不過他們的申請並沒有被接納。最後,Thompson 在一角落裡發現了一台很少人用的 PDP-7 (Programmed Data Processor) 。

PDP-7 是迪吉多 (Digital Equipment Corporation, DEC) 在 1964 年進出的迷你電腦 (minicomputer) 。這台約和 Commodore 64 同級的電腦的作業系統對於 Thompson 來說十分簡陋,於是 Thompson 就順帶以他在 Multics 計劃中學到的技術和經驗,為這台過時的電腦上撰寫一套新作業系統。這套作業系統有很多構想是來自 Multics ,包括樹狀結構 (tree-structured) 的檔案系統、用戶層面的命令解釋器 (Command Interpreter) ,簡單表現文字檔及對週邊設備 (Device) 的綜合化存取等。

最初,Thompson並不是在PDP-7上撰寫他的新系統,而是先在一台GE-635上使用GEMAP組譯器(Assembler)的巨集(Macros)編寫程式,再經由一後置處理器(post processor)產生可供PDP-7讀取的紙帶(paper tape)。這樣一來一回,由GE到PDP-7,直到一個雛型的核心(Kernel)、一個編輯器(Editor)、一個組譯器(Assembler)、一個簡單的Shell(命令解釋器,Command Interpreter)及一些公用程式如rm、cat、及cp等完成了,整個系統可以自給自足後,所有開發工作才在PDP-7上繼續。

而這套作業系統最初由與 Thompson 共事的 Brian W. Kernighan (K&RC中的K) 命名為 Unics (UNiplexed Information and Computing System),和Multics開了個玩笑。1971年間改成Unix,用Uni對Multi,cs對x。提起Unix的名字,很多人都疑惑正確的寫法是全大楷的「Unix」,還是只有起首大階的’Unix’。Ritchie就解釋說「UNIX」言個寫法源自1974年CACM的文件”The UNIX Time-Sharing System”,當時這班先鋒研究者剛剛得了個新的typesetter及開發了troff。一大班人正對smallcaps字款著了迷,導致了「Unix」的產生。縱使Ritchie在往多次以Unix並不是任何句子的縮寫為理由想在幾份Bell Labs的文件用回「Unix」,最後都失敗。而後來UNIX的註冊商標也是以全大寫為準。

First Edition Unix

到了 1970 年,這班 Unix 的研究者獲得配合一台新的十六位元電腦 DEC PDP-11/20,條件就是要為 Unix 加入較佳的文件處理工具。不過台電腦迅速地送到研究者的桌上後,它的磁碟足足慢了三個月才運到。就在這機在碟未到的等候時間中,Thompson 用 PDP-11 的組合語言 (Assembly Language) 重寫了整個 Unix 核心及基本的命令。當時那台 PDP-11/20 只有 24KB 記憶體 (Memory),這個最早期的 PDP-11 版 Unix 就佔用了 12KB,其餘的記憶體就被拿來跑用戶的程式和作 RAM Disk。僅有 500KB 的磁碟空間以及在毫無記憶保護(Memory Protection) 的情況下,支持三個用戶同時作編輯和格式化文件和那群先鋒開發者繼續 Unix 的發展工作。

1971年11月,這班懶惰的開發者終於把第一版 Unix 的說明書(Manual)定稿。往後每一由 Bell Labs 發展出來 Unix 的版本都以同時出版的說明文件的版號為準。如所謂 Unix Version 1 (V1) 其實就是指第一版 (First Edition) Unix 說明書所載的 Unix。所以在 Bell Labs 內部一直都稱呼 nth Edition Unix,不是外間的 Unix Version n。V1已有了基本的檔案系統、fork()、roff (troff 的前身)及 ed 等,並被用作處理專利文件的工具。而 pipe() 就在第二版 (Version 2) 中初次出現。

C 的誕生

在開發 V1 時,由於 PDP-7 和 PDP-11 的組合語言差異很大,令移植的工作非常因難。Thompson 這時突發奇想,覺得如用高階語言 (High-level Langauge) 來撰寫 Unix,移植和維>護的工作都會變得簡單得多。對於 C 語言極度盛行的今日,這想法可能不怎麼。但在當時>絕對是十分瘋狂,執行效率要高且記憶體使用要省的系統程式(System Software)必需要用>組合語言來撰寫的觀念早已根植在當時每一個電腦人心中。

Thompson 首先嘗試使用 FORTRAN 來寫,不過沒有成功。後來他找來一個叫 BCPL 的語言,在使用期間整理了 BCPL 的若干功能,成了另一個新的程式語言 B。V1 中就有少量公用程>式是用B來撰寫。後來 Ritchie 加入了 Unix 的開發行列,很快發現了 B 語言有若干缺點>,如資料型態(Data Type)的缺乏等。 Ritchie 著手改良 B 語言,誕生了著名的C語言。

1973年初,C 語言的重要特性大都完成了。在各方條件都足夠的情況下,Thompson、Ritchie及他們的同伴在同年的夏天把 Unix 的核心用 C 重寫。這也是所謂的第四版(Version 4, V4),有九成多的程式碼是用 C 來寫。在整個操作系統史上,這是一件很重要的事,也是 Unix 的轉折點。這意味著 Unix 可以很容易被修改,也使其成為第一個在源程式層面上可移值(source-portable)的操作系統,可以在很短時間移值(port)另一台的電腦中。

接下來的就沒有再寫了…… -P


Share It: [del.icio.us] [Technorati] [Google Bookmark] [Yahoo MyWeb] [Furl]


One line shell command to show the top referer of your WWW site

First show you the big monster:

egrep ‘HTTP/[0-9.]*” *[23][0-9][0-9]’ access.log | \
  egrep -iv ‘\.(js|css|jpg|jpeg|png|gif)[” ]’ | \
  sed -e ’s/^.*HTTP\/[0-9.]\+”\?[[:space:]]\+[0-9]\+[[:space:]]\+\(-\|[0-9]\+\)[[:space:]]\+”\?//i’ \
    -e ’s/”.*$//’ | \
  egrep -v ‘^-’ | egrep -v ‘blog\.xychen\.org’ | \
  sed -e ’s/^http:\/\/[^\/]*\(\.google\.\|google\.pchome\|google\.sina\).*q=\([^&]*\).*$/[Google]:\2/i’  \
    -e ’s/^http:\/\/[^\/]*search\.yahoo\..*[^a-z0-9]p=\([^&]*\).*$/[Yahoo]:\1/i’ \
    -e ’s/^http:\/\/[^\/]*\.soso\..*[^a-z0-9]w=\([^&]*\).*$/[SoSo]:\1/i’ \
    -e ’s/^http:\/\/[^\/]*\.baidu\..*[^a-z0-9]wd=\([^&]*\).*$/[Baidu]:\1/i’ \
    -e ’s/^http:\/\/[^\/]*\.hisearch\.hinet\..*[^a-z0-9]k=\([^&]*\).*$/[Hinet]:\1/i’ \
    -e ’s/=/=3D/g’ -e ’s/%\([0-9A-F][0-9A-F]\)/=\1/gi’ | recode /QP.. | \
  sort | uniq -c | sort -nr | head

Here is the output of My blog:

     15 [Google]:中文字型
     12 [Yahoo]:速成字碼表
      9 [Google]:Beryl
      9 [Google]:beryl
      8 http://planet.debian.org.hk/
      7 [Google]: scim
      6 [Google]:色弱
      6 [Google]:任性
      5 http://www2.shoutmix.com/?sidekick
      4 http://www2.cbox.ws/box/?boxid=1129960&boxtag=9722&sec=main

It show me that 15 visits came to my site while searching “中文字型” with Google. 12 visits from searching “速成字碼表” with Yahoo. You can write a program to analyze the referer entry in your WW site log to obtain the above result. But I just show you how to do that with one line shell command. Sure, it might better to rewrite it with Perl while the one line shell command involve too many utilities and become too complex. But I had already finish it, why not share it.

First, I would like to filter out those unsuccessful visits and requests that only getting the images/javascript code/stylesheets:

egrep 'HTTP/[0-9.]*” *[23][0-9][0-9]‘ access.log | \
  egrep -iv ‘\.(js|css|jpg|jpeg|png|gif)[” ]

Then I need to dig out the referer from the log. I try to filter out the characters before and after the referer:

sed -e 's/^.*HTTP\/[0-9.]\+"\?[[:space:]]\+[0-9]\+[[:space:]]\+\(-\|[0-9]\+\)[[:space:]]\+"\?//i' \
  -e 's/".*$//' access.log >referer.log

Sure I don’t want to count the referer from my own site and request without referer:

 egrep -v '^-' referer.log | egrep -v 'blog\.xychen\.org'

Up to now, you can already pipe the result to the old shell trick - “sort | uniq -c | sort -nr | head” to show the top 10. However, being a crazy guy, I would like to group the refer from search engine (This part is complex and should be better using perl to handle it):

sed -e 's/^http:\/\/[^\/]*\(\.google\.\|google\.pchome\|google\.sina\).*q=\([^&]*\).*$/[Google]:\2/i'  \
  -e 's/^http:\/\/[^\/]*search\.yahoo\..*[^a-z0-9]p=\([^&]*\).*$/[Yahoo]:\1/i' \
  -e 's/^http:\/\/[^\/]*\.soso\..*[^a-z0-9]w=\([^&]*\).*$/[SoSo]:\1/i' \
  -e 's/^http:\/\/[^\/]*\.baidu\..*[^a-z0-9]wd=\([^&]*\).*$/[Baidu]:\1/i' \
  -e 's/^http:\/\/[^\/]*\.hisearch\.hinet\..*[^a-z0-9]k=\([^&]*\).*$/[Hinet]:\1/i' referer.log

While I’m insane, I even don’t want see those “%2F%e6“. Pls give me the “real” characters.

  sed -e 's/=/=3D/g' -e 's/%\([0-9A-F][0-9A-F]\)/=\1/gi' | recode /QP.. referer.log

I convert the URI encoding to Quota-Printable and decode it with recode. OK, now, I can use the old shell magic to get the top 10. First I sort it to group the same referer.

sort referer.log

Kick out the repeated line, left one only and the number of it had repeat.

sort referer.log | uniq -c

Sort the result with no. of repeat:

sort referer.log | uniq -c | sort -nr

Show only the top 10:

sort referer.log | uniq -c | sort -nr | head

Known problem

  1. It only a quick trick. I haven’t optimize it yet. Any recommendation?
  2. Fail to show the search keyword with the correct encoding. Most search engine use UTF8 but CN engine love GB2312 and some TW engine seems still using stupid Big5. Ummm… I nearly forget the zh-autoconvert…. Oops, zh-autoconvert can’t distinguish the UTF8 with Big5 or GB2312.

Share It: [del.icio.us] [Technorati] [Google Bookmark] [Yahoo MyWeb] [Furl]


Based on Fluidity© 1998-2007 Roy Hiu-yeung Chan