今天需要在java代码中检查被try…catch…忽略的异常,一个文件一个文件的搜索太过繁琐且容易出错。把所有改动加入到svn的某个changelist中,用svn diff输出所有的改动。然后vim+grep。
顺便想像一下sed可以怎么做。
以前对sed的利用完全停留在sed s/abc/123上面,偶尔用到n p几个命令。今天查manual才知道,原来sed把/PATTERN/称做一个Address,而地址还可以嵌套成Range。例如/PATTERN/,+4就是指从PATTERN开始连续的5行。而命令p等,是可以应用在一个区间后的。
所以
cat ~/XMLPROD-32.diff | sed -n -e '/catch/i===' -e '/catch/,+2p'
Post by : cooper
Post under : Coding, bash, Java, linux, script, sed
on May 11th, 2010 | No Comments »
Many many times, we need to deal with the utilities output. There’s always a problem troubling me. For example, I want to handle the output of ls command when some filename contains space in it. It’s easy for one file result. But things get more complex when I need to travel through all the files. Because the results will split to array by not only the newline sperator but also space. Google told me nothing maybe for the wrong keywords. But now, I figure out one,
result=`svn st | sed -r -e 's/^\? +//' -e 's/ /{{SPACE}}/'`
for file in ${result[@]}
do
file=`echo "$file" | sed 's/{{SPACE}}/ /'`
rm -rf "$file"
done
Actually, it’s a part of my script svn.rmrevert. It revert the whole working copy and remove the files not in the repository.
Post by : cooper
Post under : Coding, bash, linux, script, shell, svn
on April 21st, 2010 | No Comments »
今天突然想到的一个用法:)
灵感来源于这个用于写文件时的权限提升的命令。
:w !sudo tee %
我的问题是这样的:当在Natilus或者Windows Explorer中用VIM打开文件时,VIM的当前目录并没有切换到当前目录。所以我想到了
:cd !dirname %
可惜它不能工作。稍作改进
:cd `dirname %`
很好! 最后我直接把它丢到了.vimrc。当然,其实还可以把它放入一个au中,根据文件类型来判断是否需要切换目录:)
Update Apr.15 2010,更好的解决方案:
au BufReadPost /* lcd %:h
区别如下:
- 使用autocmd来自动调用命令
- BufReadPost的模式为/*,这样可以过滤掉用vim http://…和vim scp://…等方式打开的缓冲区
- lcd和cd的区别在于前者只影响当前缓冲区
Post by : cooper
Post under : Coding, linux, Tips, VIM
on April 1st, 2010 | No Comments »
最近两个月都沉迷于shell脚本中,这从博客更新就看得出来。
开始是延时播入vpn的脚本,它解决了开机时网络不通的情况下播入vpn的问题。理论上用/etc/network/interfaces配置文件也应可以完成,但我设置了if-up还是有问题,所以就转而考虑shell脚本。
第二个shell脚本是用于中文内码转换的。平时下载得到txt文件大多是gbk编码的,但使用统一的utf8必将更加方便。iconv可以完成这个工作,但它每次只能对一个文件进行处理,显然增加了我的工作量。于是我利用脚本,对通配符进行循环并配合上tellenc对输入文件的内码进行猜测。现在的问题是tellenc的结果不一定很准确,这是只根据前10行进行猜测造成的。可能我会在这方面加入更多硬编码的干预,或者写一个更强大的tellenc来准确的得到编码。
然后就是Google离开中国时写下的一个监控工具。也就是不断的通过域名解析,ping,首页分析,反向dns等方法来观察gfw什么时候,用什么方式对Google下手。这个脚本经过几次强化已经比较完善,稍微修改一下就可以对其他的站点进行同样的监控。
还有一个脚本是用于满足我下列需要:在Apache的.htaccess文件中添加和更新若干Allow From XXX.XXX.XXX.XXX,其中XXX.XXX.XXX.XXX应该是指定的动态域名的ip。在写这个脚本的过程中,我学习到了sed的复杂用法。需要面对的是Apache配置文件的注释风格——只有行首的#被认为是注释的开始。因此我需要在每一个Allow From的上一行加上一个动态域名的md5用于识别,sed将替换掉这个md5的下一行,sed -e “/$md5/N” -e “/$md5/c# $domain : $md5\nAllow From $ip”。
还有一个小作品和这个主机分享计划的发起者Michael(bemike.org)有那么一点关系。和他在msn上的聊天中我猜测他有那么一个工具能够截屏并上传到图片分享网站。这很是让人羡慕Mac软件的优秀。于是我写了一个shell脚本来完成同样的事情:scrot用来截取屏幕,yfrog的python api将图片上传,notify-send将url在屏幕上显示,xclip用于将url复制到剪切板。最后,我还用Compiz把PrtScn,Alt+PrtScn都绑定到了这个脚本上。
最终章用于满足我下载的需求——登录到路由器上检查是否有其他电脑接入了网络。然后根据这一点来控制打开和关闭amuled。既不影响上网网速,又最大程度的利用网络,如果路由器能够对流量就进行统计就更好了。
小礼物:bash tips,如果有疑问的话请请先看这个视频。
预告:shell脚本暂时告一段落,下面Python脚本和Go语言即将登台演出。
Post by : cooper
Post under : Coding, bash, linux, script, shell
on February 1st, 2010 | No Comments »
Google正要离开中国。
计划今天晚上去来福士16楼为Google献上一束鲜花。
Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Flowers for Google
此外,还特意写了一个bash脚本来记录下这一切。以一个程序员的方法来纪念。
#!/bin/bash
export PATH="/bin:/usr/bin"
LOG=~/google.log
TMP=/tmp/google.index.html
FMT="+%Y-%m-%d %H:%M:%S"
HOST=www.g.cn
NS=202.96.209.5
while [ 1 ]
do
date "$FMT" | tee -a $LOG
ips=`dig @$NS $HOST | sed -n -r 's/^.*IN\s+A\s+(.*)$/\1/p'`
if [ -n "$ips" ]
then
for ip in $ips
do
wget -O $TMP $ip > /dev/null 2> /dev/null
google=`cat $TMP | sed -n -r "s/^.*Google.*$/OK/p" \
| sed -n -r '1p'`
if [ -n "$google" ]
then
echo "$ip OK" | tee -a $LOG
else
echo "$ip ERROR" | tee -a $LOG
fi
done
else
echo "Can't resolve the host: $HOST" | tee -a $LOG
fi
sleep 2
done
Updated on 15th Jan 2010:
升级了一下脚本,使得: 1.通过反向解析检测Google是否遭到域名劫持; 2. 支持同时检测多个Google旗下的域名.
#!/bin/bash
export PATH="/bin:/usr/bin"
LOG=~/google.log
TMP=/tmp/google.index.html
FMT="+%Y-%m-%d %H:%M:%S"
GOOGLE_DOMAINS=("www.g.cn" "www.google.cn" "www.google.com")
NS=202.96.209.5
while [ 1 ]
do
date "$FMT" | tee -a $LOG
for domain in ${GOOGLE_DOMAINS[@]}
do
echo $domain | tee -a $LOG
ips=`dig @$NS $domain \
| sed -n -r 's/^.*IN\s+A\s+(.*)$/\1/p'`
if [ -n "$ips" ]
then
for ip in $ips
do
server=`nslookup -q=ptr $ip \
| sed -n -r 's/^.*name = (.*)$/\1/p'`
is_server_1e100=`echo $server \
| sed -n -r 's/^.+\.1e100\.net\./OK/p'`
if [ "$is_server_1e100" = "OK" ]
then
wget -O $TMP $ip > /dev/null 2> /dev/null
is_google=`cat $TMP \
| sed -n -r "s/^.*Google.*$/OK/p" | sed -n -r '1p'`
if [ -n "$is_google" ]
then
echo "$ip OK" | tee -a $LOG
else
echo "$ip ERROR: NOT GOOGLE PAGE" | tee -a $LOG
fi
else
echo "$ip ERROR: DONAME HIJACK" | tee -a $LOG
fi
done
else
echo "ERROR: STOP RESOLVE: $domain" | tee -a $LOG
fi
done
echo "" | tee -a $LOG
sleep 2
done
Post by : cooper
Post under : Coding, Talking, bash, GFW, Google, linux, script, shell
on January 13th, 2010 | No Comments »
Notice : The music in the above article is offered just for trial, and not published under the general license of this blog.
I tied to study the shell script a few times. But on that time, I didn’t get enough knowledge to deal with it. Now, I’m back.
Situation 1
I want to startup the vpn service when the computer startup. I added pon vpn_name to rc.local. However, this can be failed because when this line execute, the network may not be ready. So I decide to write a script to do this. It will wait until the Internet up. Here’s it.
#!/bin/bash
sleep_time=1
export PATH=$PATH:/usr/bin
while [ 1 ]
do
ping_success=`ping -c 1 -n vpn.yegong.net | \
sed -n -r 's/^.* (.) received.*$/\1/p'`
if [ $ping_success -eq 1 ]
then
pon yegong
exit 0
fi
sleep $sleep_time
sleep_time=$(expr $sleep_time + 1)
done
- export PATH is very important.
- `ping -c 1 -n vpn.yegong.net | sed -n -r ‘s/^.* (.) received.*$/\1/p’`, using ` surround the command to get the output text.
- sed -n -r ‘s/^.* (.) received.*$/\1/p’, using sed to simplify the output. It’s the regular expression. Very similar with VIM replace syntax, isn’t it?
- if [ $ping_success -eq 1 ], [ condition ] means the test program, equivalent to test condition, so man test will show more usage.
- sleep_time=$(expr $sleep_time + 1), it seems that every variable in shell is a string, so you can’t simply write x=x+1. Instead of, expr program read a string expression and output the results. Please notice the space in the expression.
Situation 2
For each text files in a directory, convert the file encoding to utf8.
There’s a simple util can guess the file encoding. It can be found at Wu Yongwei’s Programming Page (Can’t access when I write the article). Then I just need a script to combine the tellenc and iconv.
TMP_FILE="/tmp/utf8lize.output"
ENCODING="utf-8"
if [ $# == 0 ]
then
echo "Usage: utf8lize FILES"
exit 1
fi
for f in "$@"
do
if [ -f "$f" ]
then
enc=`tellenc "$f"`
if [ $enc != $ENCODING ] && [ $enc != "binary" ]
then
echo $f : $enc
cp "$f" "$f.bak"
iconv -f "$enc" -t "$ENCODING" -o "$TMP_FILE" "$f"
cp "$TMP_FILE" "$f"
rm -f "$TMP_FILE"
fi
fi
done
- $# results the number of arguments when it been executed.
- for f in “$@” is the for-each loop. And “$@” indicates the all program arguments. In addition, when you run the program utf8lize *, * will convert to filenames array. Using the ” to surrounding $@ can deal the filename with space.
Post by : cooper
Post under : Coding, bash, linux, script, study, tutorial, 笔记
on December 15th, 2009 | No Comments »
- 利用”ayy复制后,可使用”Ayy继续复制,新的内容会添加到寄存器a的尾部。
- 除了利用*来匹配当前光标下的单词外,还可以用表示向后查找的#。此外还有g*和g#,区别在于*,#要求严格匹配一个单词。
- 启动参数:
vim + filename,vim打开后自动把光标移动到文末
vim +/pattern filename,vim打开后自动查找pattern
- 多缓冲区编辑:
利用:n和:N在缓冲区间移动
利用:e filename来新开一个缓冲区
利用:e#回到上一个缓冲区,其中#表示上一个被编辑的缓冲区,类似的%表示当前缓冲区
- 外部命令:
:! command,执行外部命令
:!!,执行最近一次执行的外部命令
- 录制与回放:
当执行了:命令后,命令会自动存入:缓冲区,可以用@:回放
- :r !command与!!command有类似的作用,区别在于前者是插入而后者是替换
Post by : cooper
Post under : Coding, linux, Tips, VIM
on November 13th, 2009 | 8 Comments »
My girlfriend bought a new Thinkpad T400 R29 half month ago. ThinkWiki just told the wireless hardware must be Intel 5100/5300 or Intel WiMax 5150/5350. However, I failed to setup the driver.
Windows just told it’s a realtek on it. But I didn’t believe. I don’t believe because it’s too crazy for a Thinkpad to not use the Intel wireless chip.
Then things on the easy way.
- Google, then confirm that there’s no native driver for linux.
- copy the inf and sys files from windows xp. rtl8191se
- ndiswrapper. HOWTO in Chinese
- no wlan found
- remove the installed modules, revert all changes
- realtek driver for windows 2k, which is suggested by the archlinux wiki
- ndisgtk (GUI for ndiswrapper)
- found wlan0 without restart computer
Post by : cooper
Post under : Coding, driver, linux, realtek, rtl8191se, T400, wifi, wireless
on September 27th, 2009 | No Comments »
最近没更新,估计再不努力就没订阅了……
毕业论文完工之后,把系统装成了Ubuntu 9.04,这个内核终于不再和主板BIOS冲突了。
以前的_vimrc文件迁移过来有点问题,比如说Ctrl+C / Ctrl+V要替换成对应的Ctrl+Insert / Shift+Insert,但相关的配置始终无法正常工作。内事不决问Manual,外事不决问Google,于是我开始查阅VIM的用户手册,顺便补充一下相关的知识。
- VIM可以在两次不同的更改间切换,例如输入一段文字,undo,再输入另外一段文字。普通的文字编辑软件无法恢复被undo掉的操作,但VIM可以。
相关命令:undo, undolist, earlier, later
链接
- 使用Ctrl+Insert / Shift+Insert进行复制粘贴。”+表示代表剪切板的寄存器+,此外还有代表当前选择区域的寄存器*,参见第4条。
vnoremap <C-Insert> "+y
vnoremap <S-Insert> "+gP
- 使用vimdiff作比较
相关程序:vimdiff
相关命令:vertical, diffsplit, diffpatch, diffupdate
链接
- x系统中存在这当前选中区一说,只需要用Visual模式、Visual Block模式 (Windows上按Ctrl + Q进入,Linux上按Ctrl + V进入) 选择一段文本,就可以在其它程序中点击中键将其贴出。这一点不仅限于VIM,连Firefox都可以。
- diw和daw可以删除光标所在单词而不需要把光标移动到单词开始的位置,区别在于是否删除空格字符。
- 缓存区相关的命令:buffers, ls, buffer, sbuffer,
链接
- :%s/<old>/<new>/gce中的c表示在每次替换前提示,而e表示找不到被替换的文本不是错误。
- :g/<pattern>/<Ex-command>用于在匹配成功的行上执行Ex模式命令,如果需要执行普通命令,使用normal,:g/private/normal dd。与此相反的,:v表示在匹配不成功的行上执行命令。
- g<Ctrl+G>可计算文章内的单词数,在Visual模式下也有效。
- K可以显示当前单词对应的Manual。但更好的做法是在.vimrc中导入runtime! ftplugin/man.vim,然后使用Man命令,这个方法可以将Manual在split window中打开。
- 使用:grep <pattern> <fileset>来匹配,结果会放入到clist中,可使用:cn和:cp进行光标移动。
- 使用`.来回到上一次修改的位置。
- 使用q:这个命令来打开命令窗口。
- 查找命令/<pattern>后面可以跟上光标定位偏移,例如/hello/2、/hello/e+2、/hello/b-2。同理,反向查找?也可以写作?hello?e
- gq操作符用于定宽段落重排。
- 用Visual模式选中后直接进入命令模式,会自动指定缓存区为’<,’>,即Visual选中区域。
- 使用surround.vim插件:修改cs<old_surround><new_surround>,新建ys<target-object> (例如iw或者yss)
Post by : cooper
Post under : Coding, linux, Tips, VIM
on June 28th, 2009 | 1 Comment »
前天晚上在京东买了一台电脑,昨天傍晚送到,花了一晚上的功夫才把它装好。
早上起来开始装操作系统,没想到openSUSE 11的光盘插进去,选择Install,然后在加载Kernel的第一步就死掉了。选择文本的安装模式一看,提提示 BUG Int 14 : CR2 ffb41000。
上网查了一下,14号中断原来是给换页错误用的。首先被怀疑的就是4G内存。回到BIOS关闭Memory remap,问题依旧。
用Google搜索了一下英文的内容,发现有人和我有同样的问题,而且还是同样的主板:ASUS P5QL-PRO。看下去,原来这是Linux Kernel的一个bug。如果某块数据在某页第一个字节结束的情况下,Linux错误的把页卸载了。恰好,ASUS P5QL-PRO的DMI表就满足这个情况。
打电话给ASUS的技术支持,询问是否有办法调整这一问题,没想到差点被雷死。她说:“P5QL是一款家用型的主板,华硕家用型的主板都是按Windows平台设计的。”
这下晕了,还好,似乎只有2.6.26的核受到影响,我还有得用。
Post by : cooper
Post under : Writing, bug, linux, P5QL-PRO, 华硕
on October 30th, 2008 | 1 Comment »