2012-06-24

黃昏之後

不知道為什麼,下班後回去的是已經空很久的家。隨便晃一晃,天色漸漸變暗。後陽台自顧自活得很好的綠色植物,剛剛還能投我以生氣勃勃的面目,而此刻轉身回屋,這個房間那個房間地閒步走走,就到了似乎應該開起大燈的時候。

不開大燈有點不自在。

但是以前,我們並不是那麼喜歡開燈。在昏暗之中,各自就著身旁的光亮,自顧自地,即使沒有天光,僅只要有熟悉的生命氣息,就能補足一切,自給自足。

起先我想要不理會這種嘆息,有點疲倦地把自己丟在沙發上。沙發這些年來已經殘舊了,還兀自看守這偌大的客廳。一旦不再走動,黑暗襲來的力量是驚人的。難怪大家都走了。玄關變得灰淡,而做為隔間用的每一扇門雖然仍是習慣性地都沒有關上,卻只是浸滲出種種不確定。餐桌上是什麼還留在那裡?流理台上那些不再有人理會的工具孤單嗎?書桌上紙條本裡隨手記寫的東西有可能增加嗎?電腦不再開機會受到濕氣的威脅吧?把電腦開機試試看如何?

我想至少應該記得開電視。這是電視該出聲的時候了。但是遙控器卻顯得陌生,突然之間才想起來,對於這台修了好幾次的早期電漿電視來說,另外加上去的散熱開關很重要。但是我迷惑了,好像還有音響要一起照顧。以前慣常開著的什麼都關掉了。於是好像連看電視都不會了。

讓電視響著。

但其實我沒那麼想看。才一下子就厭倦了。正要把所有開關重新關掉的時候,妹妹卻進屋來。不曉得為什麼她出現在這裡。但是我們都沒有多說什麼。就像都剛下班,就像以前一樣。我說,遙控器給你,我不要看了。

她三兩下隨便按按,廣播裡的音樂響起,電視的聲音就沒了。我看她已經把遙控器放下來,就想著,那電視還是關掉吧。卻一時手忙手亂,又想不起該怎麼辦了。又把遙控器給她,她一下子就搞定。

於是這個夜晚,在失去燈光的陌生空氣裡,靜默地,好像闖進熟悉的生命氣息。好像是假的。好像是真的。
  

2012-06-16

太陽底下的新鮮事 1

因為沒有失去什麼就不能活的緣故,才能苟延殘喘至今,也沒有非要得到什麼不可,才能隨隨便便存在著。對什麼都有興趣,對什麼都沒興趣,是好好活著的方式。這樣做就對了。

不管是工作還是生活,只要不是自找麻煩,盡其所能多樣化就對了。沒有可以主宰自己的,也沒有要主宰什麼,保有任何人全身而退的自由是重要的。這樣做就對了。

想清楚再做決定,做了決定就不退縮不後悔。沒把握的事情,最好別輕易說出口。這個鐵則在任何方面都得到過驗證,必須遵守是毫無疑義的。

對於王先生來說,活著的道理就是這樣。他想,沒有政黨可以挾持我,沒有老闆可以挾持我,沒有女人可以挾持我,而爸媽廣義說來也不再是現在進行式了,徹底貫徹自己的生存法則,實在是沒有什麼不可能的。但是就在剛剛,他講出從來沒想到過的話:「失去你,我就不能活了。」

剛過四十歲的王先生,不是沒有談過戀愛。跟政黨、跟工作、跟女人,他都有過甜蜜的時光,也都有過苦惱的抉擇時刻。到了該做出決定的時候,他總是問自己一個問題,「沒這個就活不下去了嗎」,答案永遠是「哪有這回事」。「世界上沒有什麼是不能取代的」,不管是自己要走還是面對挽留,這是他最愛的口頭禪之一。

「大概一定會失去你。失去你,我就不能活了。」這個念頭在腦子裡冒出來的那一剎那,他想,不能活的意思豈非生無可戀到極點,事情怎麼會變成這樣。既然如此,那麼要怎麼做才能不活呢?自然一點的方法比較好,於是立刻就決定好方法,但又想到,在此之前,答應別人的事情全部都要做完才行,這樣一拖大概是半年吧。

既然每個人都有自己設定的標準,沒有什麼可以退讓的,那麼事情大概成定局了吧。連不活的方法都可以很快做出結論,這樣看來,明快地想好後續步驟,大概可以算是王先生的強項之一吧。


dindela.com

沒多久,王先生把這些話都告訴對方。這麼弱智的話,不但從腦子裡冒出來,還講出來。好好的人怎麼會變成這樣。不料對方卻說,「只要你不推開我」。王先生心想,可是在此之前,在這個念頭冒出來之前,依照生存法則,不是應該速戰速決,一切歸零嗎?「失去你」和「失去自己」要如何抉擇?沒有在還能全身而退的時候趕快走掉,實在失策。

結果,在不知如何是好的這一刻,情勢發展詭異得好像這幾個小時什麼都沒發生過似的。但是這個「失去就不能活」到底是什麼意思?這件事實在是讓他大為震驚。王先生心想,難道四十年累積出來的生存法則就這樣報銷了嗎?有那麼經不起考驗嗎?為什麼非得在「失去你」和「失去自己」之間做抉擇,完全沒有商量餘地。真的是相當艱難的情勢。

不要以為計算機可以算出愛情的答案。雖然暫時這樣安慰自己,而且在事情未起變化之前,也毅然決然想好後續步驟了,王先生還是很難接受「失去就不能活」的事態。這是個比重的問題。「太陽底下真的會有新鮮事啊……」然而就算再不可思議,也不能長得像鴕鳥一樣。他暗想,是生是死都好,對方幫不幫忙也罷,這事情不能這樣就算了。

就算是死到臨頭,還是要追根究底。非如此不可。
  

2012-06-03

只想要好感

不認真理出事實脈絡就算了,卻去蠱惑記憶才是重要的。真的是很糟糕。

洪蘭在其專業上、在使其專業普及方面,或許有獨到之處,但偶爾看到她的文章,常常覺得亂七八糟。例如這一篇,〈給人民留下「不痛」的記憶〉(2012-05-29),給馬英九的建議竟然變成,要讓好的感覺超過討厭的作為,因為對人來說,留下來的是記憶,哪一樣在記憶這一仗打贏,那麼對人民來說你就是這樣的人。

她文中在列舉實驗時,也分明知道自己說的是,在比較之下,記憶告訴你某樣比較不痛,那麼大家就寧願選比較不痛的,也就是訴諸感覺如何,而非理智分析。對於治理國家的總統,不以訴諸事理行進之應然實然為重,卻以玩弄人民感覺之應然實然為出發點,而所提的建議例又是緣木求魚,這類人也真是不食人間煙火到了一個程度。如此變調的循循善誘說辭,想來自身也是相當滿意。

兩邊人馬的共通點就是想要有「好的感覺」吧,其他都是各說各話,彼此對牛彈琴,教人不敢恭維。結果只能是好感 881。
  

受難者的集體記憶

台灣人似乎不喜歡記事情記太久,很容易就忘掉很重要但新聞熱度已過的事情,特別是政治方面。凡事與政治掛上勾,就容易輕易遺忘。

我們會記得八卦,記得誰對自己好或不好,記得各個店家的態度,以做為社會關係的發展憑藉。重大社會事件也會記得,例如搶案。重大金融事件也會記得。再擴大一點就難了,例如公共事務。再擴大一點就更難了,例如政治事務。後兩者有時候根本連發生什麼事都不知道。

再從另一方面來看,遺忘速度的快慢及關心程度的強弱,跟該事件是否具有個人性似乎有密切關係。事件主角是個人,或者事情與自身有關,比較容易受到青睞。如果是公共議題或政治議題,關係到多數人的事情,似乎比較難提得起勁。

不曉得別的國家情形怎樣。究竟是人類皆如此,還是台灣人尤其嚴重。

上面說的事情都沒有舉例,好像鐵口直斷似地。

只是一種觀察,然後生出一種設想。

為什麼偏好個人性的事,不關心與多數人有關的事?因為好多人都因為關心那些事情死了。留下來的人雖然沒有死,但承受了同樣的時代心情,這樣的記憶太清楚,它不能宣之於口,於是在集體記憶裡保存下來。集體記憶告訴潛意識,那些東西不要碰。

如果是這樣,也到了該重寫集體記憶的時候了。人數夠多,就重寫得成吧。不要讓討厭、害怕的事情留在潛意識裡,那樣很不健康。

假設以上所述所真,則重寫集體記憶,很重要的一步應該還是所謂轉型正義。除了有識之士的努力,一般性的人數夠多應該也很重要。真想喊喊「讓我們衝破集體記憶的窠臼」這樣的話。可是我連認真舉例研究一下都沒有。
  

用 xsel, sed & crontab 快速擷取網頁特定資料

寫程式的能力差,要做什麼事就不會想到要用寫程式來竟全功。

話說想要把網頁上的大盤資料例行性擷取下來,試試拿來做點什麼。最直接、直觀的做法就是每天到特定網頁去把資料反白複製,存到檔案裡,把不要的字去掉。

這個想法立刻招來高手的諄諄教誨。「自己動手改總有出錯的時候」、「最可靠的還是讓程式去處理」、「完整的資料有利於解決日後任何不測」。為什麼不這樣呢?為什麼不那樣呢?……於是我跟高手說一個故事。
話說張無忌在山洞裡習武有成,來到光明頂正值武林各家精英盡出大打出手之際。他在一旁納悶,明明這人的劍再往前一寸就是致命的一招,明明那人的拳再往左一點就必中對方要害,為什麼每個人都嘎然而止?難道大家在比誰有禮貌嗎?(原著小說《倚天屠龍記》 by 金庸)
「你有聽出來嗎?這是在稱讚你!但是回過頭來請明鑒,我就是不到那個階段,所以想著用這種笨方法!」

總之,高手指點明路,展開程式大法,一步步往盡可能省事的方法、最可能無誤的資料邁進。我想這是個很好的思路進展過程的例子,為了以後可以想得起來,在此把始末筆記一下。

作業系統背景

OS: Debian/Lenny
Kernel: 2.6.57.62
編碼: Big5
Window Manager: fluxbox

做法 1:運用 sed
原始資料:網頁 A。新寫/加寫檔案:tse_filter、資料檔。

本文以 http://www.cnyes.com/twstock/idx_listed/0000T.htm 這個網頁(簡稱「網頁 A」)為例,目的是擷取此頁大盤那一整塊資料裡的數據。

將整個資料區塊反白複製下來存成純文字檔 test.dat ,其內容如下:
資料原始模樣
上市
指數 7106.09 高點 7301.50
漲跌 -195.41 低點 7106.09
昨收 7301.50 總額 794.69億
項目 張數 筆數 均張
委買 7,559,840 1,565,089 4.83
委賣 6,495,225 1,487,531 4.37
成交 2,941,070 698,797 4.21
上櫃
指數 102.72 高點 105.81
漲跌 -3.09 低點 102.58
昨收 105.81 總額 111.51億
項目 張數 筆數 均張
委買 1,285,348 284,434 4.52
委賣 1,382,047 278,883 4.96
成交 433,078 121,685
配合下面這個以 sed 為主、取名為 tse_filter 的 shell-script:
#!/bin/sh
sed \
-e '/項目.*張數.*筆數.*均張/d' \
-e '/上市/d' \
-e '/上櫃/d' \
-e 's/指數[ \t]*/ /' \
-e 's/高點[ \t]*/ /' \
-e 's/漲跌[ \t]*/ /' \
-e 's/低點[ \t]*/ /' \
-e 's/昨收[ \t]*/ /' \
-e 's/總額[ \t]*/ /' \
-e 's/委買[ \t]*/ /' \
-e 's/委賣[ \t]*/ /' \
-e 's/成交[ \t]*/ /' \
-e 's/億//' | tr '\012\015\011' '\040\040\040' | sed \
-e 's/  / /g' \
-e 's/   / /g' \
-e 's/  / /g' \
-e 's/  / /g' \
-e 's/$/\n/g ' \
-e "s/^/`date "+%G%m%d"`/g "
執行
$ tse_filter < test.dat
會得到
20120601 7106.09 7301.50 -195.41 7106.09 7301.50 794.69 7,559,840 1,565,089 4.83 6,495,225 1,487,531 4.37 2,941,070 698,797 4.21 102.72 105.81 -3.09 102.58 105.81 111.51 1,285,348 284,434 4.52 1,382,047 278,883 4.96 433,078 121,685 3.56
如下執行,則會把結果存入檔案:
$ tse_filter < test.dat >> 檔名
但這麼做是無法令人滿足的。雖然如此一來只須在網頁上動一下滑鼠,但還是得動手打一行指令才能完事。

做法 2:運用 xsel、sed 及 Window Manager 的快速鍵
原始資料:網頁 A。新寫/加寫檔案:tse_filter、~/.fluxbox/keys、資料檔。

使用 xsel,配合 Window Manager 的快速鍵,以及上述 script,只要將欲複製的區塊反白後按個快速鍵,就處理好資料,並且存入檔案。(各家 Window Manager 的快速鍵格式或有不同,這裡用的是 fluxbox。)
Mod4 s :ExecCommand bash -c "xsel | tcs -f utf -t big5 | tse_filter >> 資料檔檔名"
上式是加寫在 Window Manager 快速鍵設定檔 ~/.fluxbox/keys 裡的快速鍵設定,意思是,將所要的區塊反白後,按下窗戶加 s 鍵,會執行:
  1. 呼叫 bash。以 xsel 指令複製該區塊到 buffer。
  2. 以 tcs 指令將文字編碼從 utf8 轉為 big5。
  3. 經由上述 script tse_filter 處理後,儲存到檔案裡。
但這麼做是無法令人滿足的。雖然如此一來只須在網頁上反白按一下快速鍵就自動把資料處理完畢寫入檔案,但不知執行結果是否無誤(高手)怎麼睡得著,而想查看執行結果卻還要自己動手,怎麼能算完事。

為了儲存之後可以立刻檢查一下是否正確,修改上式如下:
Mod4 s :ExecCommand bash -c "xsel | tcs -f utf -t big5 | tse_filter >> 資料檔檔名 && crxvt -e bash -c "tail 資料檔檔名 | less"
"&&" 後所增加的部分,意思如下:
  1. 呼叫 big5 的視窗及 bash 備用。
  2. 秀出資料檔最後部分。
  3. 透過 less 來看。
但這麼做是無法令人滿足的。雖然如此一來連查核都不必自己動手叫檔案,已經做到在網頁上反白按下快速鍵就存好資料而且自動跳出視窗顯示執行結果以供查核,但還是得要在一開始先叫出瀏覽器再連上網頁才行。

做法 3:運用 sed 及 crontab
原始資料:網頁 B。新寫/加寫檔案:tse_get、crontab -e、資料檔。

事情進行到這裡,跟一開始打算的做法已經天差地遠,但高手還在一直碎碎念,要是電腦定時做這件事,人都不必動手就好了。那我的內心口白是,我也知道呀。不過這的確是很好的「願景」,似乎手開始不聽惰性使喚。

事情進行到這裡,由於寫程式的感覺有點出現,就稍微認真去找原本不想認為可以找得到的該區塊原始碼到底在哪裡。因為這件事非得用到這個不可。這一整段故事裡,我的貢獻只有這個。

總之因為心神較為收束,原本覺得無論如何不會找到的東西,很快找到了。

來到這個網頁 http://traderoom.cnyes.com/tse/quote2FB.aspx?code=TS(簡稱「網頁 B」),可以得到有這些數據的原始碼。於是得出以下這個新的 shell-script,取名為 tse_get:
#!/bin/sh
SOURCE="http://traderoom.cnyes.com/tse/quote2FB.aspx?code=TSE"
TSE_ORG="/tmp/tse_org.html"
TSE_ORG_BIG5="/tmp/tse_org_big5.html"
TSE_DATA="/tmp/tse_data.html"
wget -U opera $SOURCE -O $TSE_ORG 2> /dev/null
tcs -f utf -t big5 $TSE_ORG > $TSE_ORG_BIG5 2> /dev/null
sed -n -e "s/^.*\(上市.*table>\).*$/\1/p" $TSE_ORG_BIG5 > $TSE_DATA 2> /dev/null
sed < $TSE_DATA \
-e 's/<[^<>]*>/ /g' \
-e 's/項目//g' \
-e 's/張數//g' \
-e 's/筆數//g' \
-e 's/均張//g' \
-e 's/上市//' \
-e 's/上櫃//' \
-e 's/指數[ \t]*/ /g' \
-e 's/高點[ \t]*/ /g' \
-e 's/漲跌[ \t]*/ /g' \
-e 's/低點[ \t]*/ /g' \
-e 's/昨收[ \t]*/ /g' \
-e 's/總額[ \t]*/ /g' \
-e 's/委買[ \t]*/ /g' \
-e 's/委賣[ \t]*/ /g' \
-e 's/成交[ \t]*/ /g' \
-e 's/億//g' | tr '\012\015\011' '\040\040\040' | sed \
-e 's/          / /g' \
-e 's/  / /g' \
-e 's/     / /g' \
-e 's/    / /g' \
-e 's/   / /g' \
-e 's/  / /g' \
-e 's/$/\n/g ' \
-e "s/^/`date "+%G%m%d"`/g "
exit $?
這個 script 的作用是:
  1. 以 wget 把網頁抓下來後,以 tcs 轉碼。
  2. 把所需資料以 sed 抓出來。
  3. 以 sed 留下要留住的數據。
接下來要請 crontab 出場,以便讓電腦自行定時工作。
$ crontab -e
Vim 的編輯視窗出現後,加上以下排程:
58 22 * * 1-5 /路徑/tse_get >> /路徑/資料檔 && aplay /路徑/聲音檔.wav && crxvt -display :0.0 -e bash -c "tail /路徑/資料檔 | less"
這個意思是:
  1. 禮拜一到五的 22 點 58 分,執行指定的工作。
  2. 執行 tse_get 之後,寫入檔案。
  3. 發出聲音告知工作之執行。
  4. 叫出一個視窗,以 less 秀出該檔案的最後部分。
至此,記得打開電腦,是唯一要做的事。

這件事至此告一段落,過一陣子就可以畫圖來玩了。不過美中不足的是,要是禮拜一到禮拜五遇到休市,抓下來的檔案日期可以沿用最後一個正常開市的日期就好了,那麼資料檔處理起來可以少些手續。

主程式改寫 2012-06-22

原來的 tse_get 高手說太低路,改成如下。
#!/bin/sh
SOURCE="http://traderoom.cnyes.com/tse/quote2FB.aspx?code=TSE"
TSE_ORG="/tmp/tse_org.html"
TSE_ORG_BIG5="/tmp/tse_org_big5.html"

wget -U opera "$SOURCE" -O "$TSE_ORG" 2> /dev/null
tcs -f utf -t big5 "$TSE_ORG" > "$TSE_ORG_BIG5" 2> /dev/null

grep '上市.*table' "$TSE_ORG_BIG5" | \
sed \
-e 's/<[^<>]*>/ /g' | \
tr -d  '\072-\377/' | \
sed \
-e 's/          / /g' \
-e 's/  / /g' \
-e 's/     / /g' \
-e 's/    / /g' \
-e 's/   / /g' \
-e 's/  / /g' \
-e "s/^/`date "+%G%m%dT%H%M%S"`/g " #| tee -a /home/phasma/sh/tse.dat

exit $?



番外篇:所以,以下這個程式……

但高手告誡,這樣還是無法高枕無憂。雖然只要電腦是開著的,時間一到,就會自動跳出視窗,告知當日執行結果,但是誰可以保證當睡過頭時,機器處於開機狀態?所以,以下這個程式……

是的,事實上還有停電的問題。要解決這些問題,即使有奴隸也不可靠。於是我打算開始打造機器人。在機器人有眉目之前,我準備先弄一個緊急供電設備(UPS),以及智慧型紅外線定時遙控開機裝置。聽說最好還要符合什麼 Smart Energy 2.0 規格。

巴爾札克 〈不知名的傑作〉插圖。
(圖片來源:Wikipedia
那麼我又想講一個故事:
一名畫家天天畫著一幅肖像,重覆地塗塗抹抹,一層又一層,左潤右飾,前減後添,總是達不到想要的完美境界。日復一日,永遠無法完成。最後就這樣死了。(原著小說 〈不知名的傑作〉(Le Chef-d'œuvre inconnu, 1831)by 巴爾札克)
哦,追求完善是無止境的。要求純粹是辛苦的。

(上述故事是二十幾年前看的,雖然到現在還留有震到的印象,但內容只依稀記得一點點。剛剛到 wiki 看故事大綱,果然情節是較為瘋狂的。)

番外篇:sed

最後的 script "tse_get",因為高手很忙,想說高手已經打好底了,自己來試試看。那麼因為很懶惰,所以變成埋頭苦幹。最大的問題在於 sed 在搜尋時,一尋就尋到該行最後,所以如何以簡單的方法把所有不需要的 "<.......>" 部分去掉,而有用的部分還是能留下來呢?因為不會,所以變成這樣:
sed < $TSE_DATA \
-e 's/<[tds\"\/][vhrde\"]>/ /g' \
-e 's/<[tds\"\/].[vhrde\"]>/ /g' \
-e 's/<[tds\"\/]..[vhrden\"]>/ /g' \
-e 's/<[tds\"\/]...[vhrden\"]>/ /g' \
-e 's/<[tds\"\/]....[vhrde\"]>/ /g' \
-e 's/<[tds\"\/!]...........[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]............[vhrde\" -]>//g' \
-e 's/<[tds\"\/!].............[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]..............[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]...............[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!].................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]..................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]...................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]....................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!].....................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]......................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!].......................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!]........................[vhrde\" -]>//g' \
-e 's/<[tds\"\/!].........................[vhrde\" -]>//g' \
-e 's/<.*>//g' \
那麼,雖然它會動了,動得也很正確,不過自己也知道這樣寫很可笑。果然請高手看一下
,高手立刻哭笑不得
(高手抗議說他沒有哭笑不得而是很虔誠地),他用一行就搞定了:
sed < $TSE_DATA \
-e 's/<[^<>]*>/ /g'
也就是 "^" 這個符號可以用來去除不欲使之包括在內的字元。