Werden wir Helden für einen Tag

Home | About | Archive

Unix utilities #2

Posted on Mar 22, 2012 by Chung-hong Chan

上次有讀者 hevangel 提議我用 sed 。
我於是真的去玩 sed ,試用 sed 去作點 data processing 的東西,但是卻即時撞版。最終我用了較熟的 R 去做 text processing 。
問題是這樣的。假設我有cppcc
我想將所有名稱都拆出來。
我想以下指令應該 work 的:

cat cppcc.txt | sed -e 's/^[  \t]*//;s/[  \t]*$//;s/\*//g;s/ /\n/g;/\(.*人\)$/d;/^$/d;s/\(.*\)$//'

可惜是不 work 。問題我估是在於 \(.*人\)$ 和 \(.*\)$ 兩組 regex 。我找不到 sed 是否支持 \ 的 escape character 。如果不用 \ ,即是用此指令:

cat cppcc.txt | sed -e 's/^[  \t]*//;s/[  \t]*$//;s/\*//g;s/ /\n/g;/(.*人)$/d;/^$/d;s/(.*)//'

卻會引致很多名稱消失了。請教網友, sed 的 regex 是如何 escape 的?

UPDATE:

調查過後。以下指令是 work 的,但這是 quick and dirty 作風。

cat cppcc.txt | sed -e 's/^[  \t]*//;s/[  \t]*$//;s/\*//g;s/ /\n/g;/\((.*人)\)$/d;/^$/d;s/\((女)\)//g;s/\((女,滿族)\)//g'

也許是 (*.) 太 greedy 的緣故。另一發現係 Mac OS X 版的 sed 和 Linux 的 sed 有不同。 Mac 版的是 BSD 的,而 Linux 是 GNU 的,在處理 newline 時(\n)兩者有不同,以上指令只適用於 GNU 版。

Update 2

根據讀者 Jacky 留言所寫的指令,也是 work 的。

cat cppcc.txt | sed -e '/[0-9].*/d;s/([^()]*)//g;s/\*//g;s/^[  \t]*//;s/[  \t]*$//;/^$/d;s/ /\n/g;'


Powered by Jekyll and profdr theme