2008/7

修复 Linux 文件名的脚本

肯定还有bug,欢迎指正。;-)

(下面的语法加亮有问题。。。)
[bash]

!/bin/bash

posix_chars=”a-zA-Z._0-9-“
bad_chars=”][|#?><*$'"(){}&"

onlyquery=0
only_print=0
only_posix=0
only_whitespace=0
replace_char='
'
append_chars="_2"
remove_dup_underscores=0
allow_recursion=0
start_with_dash=0

function test_name
{
if [ $only_posix -eq 0 ]
then
test_chars="[${bad_chars}]"
ret=0
while(($#!=0))
do
ret=$(($(echo "$1" | wc -l)-1))
echo "$1" | perl -n -l -e "exit 1 if m/[s]/;"
ret=$(($ret+$?))
case "$1" in
"" | - | ${test_chars}) ret=$(($ret+1))
;;
"\") ret=$(($ret+1)) #'' is special !!
;;
esac
shift
done
else
test_chars="[!$posix_chars]"
ret=0
while(($#!=0))
do
case "$1" in
"" | -
| ${test_chars}) ret=$(($ret+1))
;;
esac
shift
done
fi
return $ret
}

function goodname
{
rpl="${2:-
}"
tmp=$(echo -n "$1" | tr '[ trn]' "$rpl")
if [ $only_whitespace -eq 0 ]
then
echo $(echo "$tmp" | sed -e "s/[$bad_chars]/$rpl/g" | sed -e "s/[]/$rpl/g")
fi
}

function nodupunderscore
{
echo "$(echo "$1" | sed -e 's/_
*/
/g')"
}

assume in pwd directory

get_new_name bad_name replace_char append

function get_new_name
{
if test_name "$1"
then
if [ $remove_dup_underscores -eq 1 ]
then
echo "$(no_dup_underscore "$1")"
else
echo "$1"
fi
return
fi
apd="$3"
new_name="$(good_name "$1" $2)"
if [ $remove_dup_underscores -eq 1 ]
then
new_name=$(no_dup_underscore "${new_name}")
fi
if [ -e "${new_name}" ]
then
if [ ${new_name##.} = ${new_name} ]
then
echo "${new_name%.
}${apd}"
else
echo "${new_name%.}${apd}.${new_name##.}"
fi
else
echo "${new_name}"
fi
}

function print_version
{
echo "Copyright (C) WANG Cong, 2008."
echo "Version 1.5"
}

function print_help
{
prog=$(basename $0)
cat <&2
echo >&2
print_help >&2
return 1
fi
test_name “$@”
return $?
else
if [ $only_print -eq 0 ]
then
[ -e “$1” ] || (echo “No such file or directory.” >&2 && return 2)
fi
last_name=$(get_new_name “$1” “${replace_char}” “${append_chars}”)
if [ $only_print -eq 1 ]
then
if [ $allow_recursion -eq 1 ]
then
echo “-p conflicts with -r.” >&2
print_help >&2
return 3
else
echo “$last_name”
fi
else
[ “$1” != “$last_name” ] && mv “$1” “$last_name”
if [ $allow_recursion -eq 1 ]
then
if [ ! -d “$last_name” ]
then
echo “$1”” was not a directory!” >&2
return 4
fi
(cd “$last_name”
ls | while read file
do
echo “$file”
if [ -d “$file” ]
then
main “$file”
else
allow_recursion=0
main “$file”
fi
done)

        fi
    fi
fi
return 0

}

while getopts “rvhsuoqx:a:c:p” var
do
case $var in
v)
print_version
exit 0
;;
h)
print_help
exit 0
;;
c)
replace_char=$OPTARG
if [ ${#OPTARG} -ne 1 ]
then
echo “-c must be followed by a char.” >&2
print_help
exit 1
fi
;;
a)
append_chars=$OPTARG
;;
q)
only_query=1
;;
p)
only_print=1
;;
o)
only_posix=1
;;
r)
allow_recursion=1
;;
u)
remove_dup_underscores=1
;;
s)
only_whitespace=1
;;
x)
start_with_dash=1
tmp=$OPTARG
;;
*)
echo “Bad options!” >&2
print_help
exit 1
esac
done

shift $(($OPTIND - 1))
if [ $start_with_dash -eq 0 ]
then
main “$@”
else
tmp=$(perl -e ‘$foo=”‘“$tmp”‘“;$bar=$foo;$foo=~s/^-*//;rename(“$bar”, “$foo”);print $foo;’)
main “$tmp”
fi
exit $?

[/bash]

真的老了?

最近发现自己真的有变老的迹象,证据如下:

1. 对年轻人越来越有耐心了;
2. 越来越感觉自己学到的东西很简单,于是经常自嘲;
3. 喜欢上蔡琴的歌了……囧rz;
4. 越来越喜欢回忆过去了,感觉过去的很多时光很美好,后悔自己当时不知道珍惜;
5. 越来越懂得享受生活了,慢慢地感觉到生活才是最重要的;
6. 对感情越来越平淡了,一切顺其自然;
7. 越来越不想去计划未来了,走一步算一步;
8. 感觉最重要的是要过得快乐,其它什么都不重要;
9. 越来越珍惜自己身边的朋友和亲人了;
10.人生经历甚丰富了,事情越来越看得开了,烦恼的事能慢慢不放心上了;
11.越来越经常地发一些人生感慨。

恩,一口气列了11条,感觉自己都快成为一个老人了,为了平衡一下心理,再列举几条自己还年轻的证据:

1. 发现想学的东西越来越多了,计划去学的东西有一大堆;
2. 越来越喜欢旅游了,梦想着在有生之年能游历全世界;
3. 喜欢聚会,不想自己一个人呆着,尤其是周末;
4. 仍然喜欢变着法地折腾,喜欢尝试新奇的东西,喜欢刺激,有挑战性。

哎,总的来看还是老了……

到这里一个月了

不知不觉中到葡国已经一个月了,时间过得太快啦!

那天还在公交车上和George谈论“how time flies”这个问题,哎,他快要回罗马尼亚了~~说实话,真舍不得让这伙计走,他是个很好的人,又恰巧和我一样是大学刚毕业(人家大学本科读5年,9月才毕业,回去就基本上算是毕业了),所以和他有很多话题。希望他以后能到University of Coimbra来读研究生,这样我们又能见面啦!

-------

前几天换公寓了,搬到一个山头上去了,我承认,那里景色很美,但是在那里坐公交车上班很麻烦。和我同住的两个同事人家都有自己的车,不过作息时间不一样,不能赶到一起上下班(所以你也可以看出Critical的工作时间有多宽松)。而且暂时还没有无线网络,需要给房东说。最关键的是,不像以前免费了,需要自己交房租,水电费等,哎~~不过还好,相对于其它的房子这个很便宜了。

-------

我有个大的发现,lady是个无敌的词。在商店里,你可以说某个女售货员是lady;在银行里,你也可以说哪个女接待是lady;在公寓里,你还可以说房东是the lady,说打扫房子的女清洁工为the cleaning lady。不知道我们公司的Fatima能不能被称为“Our Lady of Fatima”?;-)

-------

有件比较囧的事是,我的名字被同事们普遍念作“wang kong”……我宁愿他们像George那样直接叫我wang。我想原因很简单吧,“c”在英语里都读作/k/或者/s/,而在葡语里基本上就是/k/了,所以估计他们都不会念咱们拼音中的/c/这个音……就像我,很多葡萄牙人的名字我都读不通……期待着去大学里找个葡语课学学,也省得周末没啥事干~~

-------

昨天又是公司的Beer Lifting和聚餐,又赶到了一起,果真一个月了。这次我们去的是一家意大利餐馆,而且还在某个山头上,老远,搭同事的车过去,路上拐了不下20个弯……头一次吃意大利菜,很好吃,除了感觉牛肉有点儿不熟,甜点很美。这次晚上又是吃到很晚,我回到公寓都一点多了……巨困,躺到床上就睡着了。

很期待公司两周以后的划船比赛,噢,伟大,万能,无敌的Mondego~~!

期待着下个月去SintraCabo da Roca

Figueira da Foz

Figueira da Foz是个很美的海边小镇,也是离Coimbra最近的海边,坐火车一个小时就到(这种火车基本上相当于北京的地铁,每个小站都停)。Coimbra的人们夏天经常去那里度假,因为那里有个很大很大很大的海滩。

上周周末我们几个人一起去了那里,在去之前我正好买了一个数码相机,佳能A720is。于是乎我猛拍了不少照片,都放在>这里<了。

去海滩之前我们在路上拍了Figueira的不少其它景色,也很漂亮。路上还发现一个“集市”,有很多卖东西的,George买了一些纪念品,准备带回国送朋友;我买了一顶帽子,上面写着“Figueira da Foz”,感觉很酷。8-)

那里那个沙滩超级大,走不到头。去的那天海边正好风大,结果我和George尝到了真正的“沙尘暴”的滋味,弄得浑身上下全是沙……后来我们找到一个避风的地方,晒了个日光浴,回来发现我被晒黑了……本来想坐晚上8点多的火车回去,结果George建议说看日落,只能坐晚上10点半的火车回去了。不过那的日落确实很美,等了那么久没白等,日落的照片也在上面那个相册里。结果,那天晚上回到公寓已经夜里12点多了……

总之,如果你来葡萄牙,千万别错过Figueira da Foz!

Coimbra节日

上周五是Coimbra的纪念日,全城放假,我和George一起去市中心看了一场极具葡萄牙特色的活动。

下午4点多的时候,我们先去了Mondego河边的公园,那里都已经搭好舞台了,但是等了几分钟还是没看到有开始的迹象,于是我们去决定去市中心的广场去看看。结果在路上正好遇到表演的队伍向公园挺进。刚看到时很是吃惊,人们穿着各种各样的古装,打扮成各种阶层的人,边走边唱,时而还击掌来伴奏,很有气氛,如果你像我一样站到旁边看的话,你可能也会情不自禁地跟着它们一起击掌。

我仔细观察了一下,整个队伍分成一个个的小组,不同的组应该是来自Coimbra的不同的小镇,它们都有自己的旗帜或标识,由最前面的小孩举着。小孩们都很可爱,也是打扮成各种各样,有的拿着布娃娃,有的还提着花篮。小孩后面是妇女和成年男子,有年轻的也有年长的。女的头上多顶着各种蔬菜和食物,大概她们劳动时就是这样吧!男的多打扮成绅士或者农夫,和旁边的女的成对出现,因为他们是舞伴。每组中都有一些吹拉弹唱的人,可以看到各种各样的乐器。

等到整个队伍都到了公园里的舞台后,演出就开始了。舞台下面有一些椅子,不过都是给老年人或者带小孩的人坐的,像我们这种年轻人只能站着看,人们都很自觉。表演刚开始时还不时地从空中飞过一些前来助兴的飞机,结果很多人都被吸引了过去,飞机飞过后然后再回来,然后再过去……说说表演。表演是一个镇一个镇的上,上去时先在台上转一圈,边走边唱,同时把手里拿的或者头上顶的东西全都放到边上,让孩子们坐到边上看,大人们开始表演。表演开始前都会自我介绍自己的小镇,可我除了Mondego和Obrigado啥都听不懂……正式表演都是唱歌和舞蹈,主唱的一般是后面的几个中年妇女,她们站那里专门唱歌,而且声音很是洪亮。吹拉弹唱的站在她们旁边伴奏。最前面的是跳舞的,都是一男一女搭配,他们也会跟着唱歌。看他们跳舞很有意思,时而成对,时而转圈,最让我觉得有意思的是一种男女交叉着走的舞蹈。他们唱的歌词虽然我都听不懂,不过光是听音乐,也能感觉到浓厚的葡萄牙气息。给我印象最深刻的是一首边击掌边唱的歌,听着很带劲,感觉很好听。还好George录了这首歌,所以我还可以回顾回顾。

到了晚上,在市中心还可以看到各种彩灯,整个街都被装点得很美。路边还有一个很大的彩灯,样子像是一个女神,据说这里的人们都相信Coimbra的美好生活是拜她所赐。

静静的Mondego河上倒映着这个城市的夜景,在夜色下,它也是那么迷人……

(P.S. 浏览更多照片请猛击这里。 P.P.S. 当时看到一个超级可爱的小美女!相册里有!)

全新的Fedora系统

这两天对我的Linux进行了大的改造。

先是花了一个晚上的时间从Fedora 8升级到了Fedora 9。通过网络升级Fedora有两种方式:一种是通过preupgrade,另一种是直接用yum(关于两种升级方式可以参考:preupgradeyum)。我采用了后者,升级过程中遇到了包依赖的错误,解决方法很简单,哪个包缺少依赖的东西就把那个包给删除,升级完再重新安装,然后就是要使劲地yum clean all。

升级完最让我眼前一亮的是登录界面和Firefox 3,感觉很漂亮。升级后mplayer会出现错误,解决方法是:这个。还有一个头疼的问题是gcc 4.3,一些软件编译不过去了,某个2.6.23的内核就是,害得我又修改了内核的Makefile才编译通过的,不知道以后还会有什么,看来得自己编译gcc了。

另一个大的改造是在Gnome上放弃使用metacity,改用sawfish,感觉要轻便一些。不过安装sawfish需要自己编译安装。同时,默认使用fluxbox,其次是enlightenment 16,减少Gnome的使用。用了几天感觉这两个窗口管理器都很简洁,fluxbox更顺手一些,虽然e16更漂亮,但它资料太少(注:e17资料相对还多一些),不知怎么去修改它的配置,所以默认使用fluxbox了。安装它们可以用:yum install fluxbox e16。

推荐几个关于enlightenment的网址:get-e.orge17-stuff.org官方wiki,关于fluxbox的网址:fluxbox-wikifluxbox.org

顺带体验了一下rox,感觉安装很方便,就是用着还不顺手,还是资料太少。

用脚本解决C语言问题

vvoodyxiyoulinux上提出了一个C语言的问题,这个问题我之前见过,所以不想自己想了,想让计算机帮我完成。于是费了一番功夫写了个脚本帮我完成。(哎,老了,写代码慢了~~)

先贴“答案”,应该是总共8个结果(下面的9个中有两个明显是等价的):

int i,n=99;main(){for(i=0;i<n;i—){printf(“#”);}}
int i,
n=99;main(){for(i=0;i<n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;-i<n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;~i<n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;i<&n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;i<n;i—);{printf(“#”);}}
int*i,n=99;main(){for(i=0;i<n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;i+n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;i<n;n—){printf(“#”);}}

用时:

real 1m3.881s
user 0m44.097s
sys 0m17.436s

最让我吃惊的结果是那个溢出的,很巧妙,脚本运行到那里停了大约4,5秒钟的样子。

最后放脚本,包括两部分,一部分用bash完成,另一部分用Perl完成。其实完全用bash或者完全用Perl都是可行的,而且完全用Perl应该是最快的。

[bash]

!/bin/bash

TEST_VAR=’int i,n=99;main(){for(i=0;i<n;i—){printf("#");}}'

Generated by Python with

''.join(map(lambda x: '' if chr(x).isupper() else chr(x), range(32, 127)))

except '$','(',')', '{','}', '[', ']', '@', "`", """, "#", "'", "\", ' '

possible_chars='!'"%&*+,-./0123456789:;?^_abcdefghijklmnopqrstuvwxyz|~”
len=${#TEST_VAR}
num_chars=${#possible_chars}
tmpfile=$(mktemp /tmp/test-$$.XXXXXXX)
outfile=”/tmp/test_sh.out”

function is_valid_and_ok()
{
echo $1 > $tmpfile
if gcc -xc -c -o $outfile.o $tmpfile &>/dev/null;
then
gcc -o $outfile $outfile.o &>/dev/null
if [[ $? -ne 0 ]]; then
return 0
fi

    #nohup $outfile &gt; $resultfile 2&gt; /dev/null &amp;
    #sleep 1 &amp;&amp; killall $outfile 2&gt; /dev/null
    n=$(./get_run_result.pl $outfile)
    echo $n
    if [[ $n -eq 99 ]] || [[ $n -eq 100 ]] || [[ $n -eq 1 ]]
    then
        return 1
    fi
fi
return 0

}

main

i=8
while(($i $tmp” 1>&2
fi
i=$(($i+1))
done;

i=4
while (($i < $len - 14));
do
j=0
while(($j $tmp” 1>&2
fi
j=$(($j+1))
done
i=$(($i+1))
if (($i == 11)) ; then
i=17
fi
done;

i=0
while(($i<$len - 16));
do
j=0
while(($j $tmp” 1>&2
fi
j=$(($j+1))
done
i=$(($i+1))
if (($i == 11)) ; then
i=17
fi
done;
[/bash]
[perl]

!/usr/bin/perl -w

use strict;
use warnings;

my $n;
my $chars;

open(my $in_file, “$ARGV[0]|”) or exit 1;
$n = read($in_file, $chars, 101);
print “$nn”;
close $in_file;
[/perl]

发工资了

今天是发工资的日子(pay day),比较兴奋,毕竟这是自己的第一份工资。上周就和公司的人力资源同事谈这事了,因为公司发工资不给现金,她还专门带我去银行办了信用卡,顺道带我去中餐馆吃了一顿。:-)

下午快下班时才收到银行发来的确认邮件,说多少多少钱已经转到你的帐户上。比较囧的是还差点把它当成垃圾邮件处理了,因为它的正文是放到html格式的附件中的。虽然说没有拿到实实在在的钞票,可心里还是很高兴的。

今天还有比较高兴的事是自己做的“项目”有了大的进展,开始进行下一步了,终于有机会写代码了!T_T 严重感谢公司里的一个老同事,每次当我遇到问题时总是不厌其烦的帮我,哪怕我的问题有多么地弱智。。。他有一点很让我佩服,就是,遇到一个问题,我还没反应问题是什么时他就已经找到答案了!可见他对Linux是多么熟悉!更关键的是,他知识相当渊博,编程他懂得多,很擅长C++;服务器管理他也懂,公司CVS和DHCP服务器就是他管理;硬件他还懂,给我说设计CPU多么多么简单……Orz!上次聚会时我正好坐他旁边,和他聊了很久,给我印象最深的是他的口头语,有两句,是“Oh, shit!”和“…fucking xxxx.” 还有一点让我吃惊的是他居然会4,5种语言(不是计算机编程语言,是人们说的自然语言),而上星期Fatima也告诉我她也会不下4种……Orz。难道这里的人都这么牛?

厄,还有一件事,就是skype终于可以打电话了。。。T_T 感谢ZC Miao帮我充了skype!刚刚给老妈打了个电话,那边是早上,她还没起床。

总之今天很高兴,不写了,睡觉去了。