自觉很是方便实用,所以共享一下,不过缺点也明显,如果网易的网站有所改变,脚本就得跟着修改;如果你的终端不够宽,格式会很难看,将就着用吧

功能有以下几个:
1.支持词组,要用" "号把词组引起来
2.支持一次查找多个单词/词组,用空格隔开
3.把结果加入“生词本”(其实就一文本文件)
4.彩色显示,提问和警告等,都会以不同颜色显示
5.查找过程会耗一小段时间,但会有简单的动态显示
6.加了边框格式,看起来舒服些
7.查找不到提醒
8.输入错误提醒
9.空参数是程序说明
10.详细解释用less输出,因为有些解释很长
如果有错误别忘了提醒一下,程序写得很乱

一些说明:
1.程序运行过程中会在/tmp下生成两个临时文件,正常退出程序这两个临时文件会被删除
如果你ctrl+c中断,文件很可能会留在/tmp里
2.如果把单词加入生词本,程序会生成一个~/dict文件,属性只读
程序流程:
1.用w3m下载网页,把空行过滤,重定向到第一个临时文件temp1(例如/tmp/tmp.xxxxxxx)
2.然后找到起始行和结尾行,也就是对我们有用的那部分,重定向到第二个临时文件temp2
3.从temp2文件里输出简短解释到终端
4.如果有详细解释(整个temp2文件就是所有解释),就会问题你是否也显示
5.如果是就用less打开temp2文件
6.退出less之后
7.会问你是否要加入生词本(~/dict),有两种选择,加入简短解释和详细解释
8.只有在这个时候,~/dict文件才可写,写入之后,~/dict马上又变成只读
9.程序查找下一个单词或者退出
代码: 全选
#!/bin/bash
#
#Look up an English word from dict.youdao.com
#Get the Chinese meaning, and output to ~/dict
#if you want.
#
#2010/11/26
DICT=${HOME}/dict ##生词本
URL="dict.youdao.com" ##从youdao.com查找单词
_DIV_1="---------------------------" ##传说中的分隔线
_DIV="+$_DIV_1$_DIV_1$_DIV_1+" ##还是传说中的分隔线
yn1=x ##根据这个变量判断是否加入生词本
ynd=x ##根据这个变量判断是否显示详细解释
DETAIL=1 ##如果单词有详细解释,这个变量会被置0(此刻,我想到了林志玲),默认为1
_NOW=$# ##number of word, 单词数量,就是有多少个变量的意思,根据这个变量判断是否还有“下一个”单词
###下面以msg_开头的四个函数,作用是以不同颜色输出不同信息
msg_info() { echo -ne "\033[32m$@\033[0m"; }
msg_warn() { echo -ne "\033[33m$@\033[0m"; }
msg_erro() { echo -ne "\033[31m$@\033[0m"; }
msg_ques() { echo -ne "\033[35m$@\033[0m"; }
###如果能查找到该单词,这个found()函数会被调用
found ()
{
DETAIL=1
TEMP_FILE2=`mktemp` ##生成第二个临时文件,这个临时文件用来存放第一个临时文件中,对用户有用的部分
START_LINE=$((`cat -n ${TEMP_FILE1} | grep "英汉释义.*我要报错" | awk '{print $1}'`+1)) ##有用信息从第一个临时文件的这一行开始,取其行号
grep "dict2rstar.*hidenew2" ${TEMP_FILE1} > /dev/null 2>&1 ##查找含有"dict2rstar.*hidenew2"的行
##若找到则取其行号,作为结尾行号
##否则取 "●$" 所在行行号,作为结尾行号
[ $? == 0 ] && END_LINE_2=$((`cat -n ${TEMP_FILE1} | grep "dict2rstar.*hidenew2" | awk '{print $1}'`-1)) \
|| END_LINE_2=$((`cat -n ${TEMP_FILE1} | grep "●$" | awk '{print $1}'`-1))
##END_LINE_1是简短解释的结尾行,也是详细解释的起始行,如果没有详细解释,那这两个结束行的值当然是一样的
##默认假设单词没有详细解释,所以把END_LINE_2的值赋给END_LINE_1
END_LINE_1=${END_LINE_2}
grep "▲.*▼" ${TEMP_FILE1} > /dev/null 2>&1 ##查找含有"▲.*▼"的行
[ $? == 0 ] && END_LINE_1=$((`cat -n ${TEMP_FILE1} | grep "▲.*▼" | awk '{print $1}'`-1)) ##如果找到,则说明单词含有详细解释,取其行号
LINES_1=$(($END_LINE_1-$START_LINE)) ##简短解释共有这么多行
echo "$_DIV" > ${TEMP_FILE2} ##输出边框,重定向到第二个临时文件
cat ${TEMP_FILE1} | head -n ${START_LINE} | tail -n 1 | sed 's/^/|/g' >> ${TEMP_FILE2} ##在前面加入'|'作为边框再输出单词解释,重定向到第二个临时文件
echo "$_DIV" >> ${TEMP_FILE2} ##输出边框,重定向到第二个临时文件
cat ${TEMP_FILE1} | head -n ${END_LINE_1} | tail -n ${LINES_1} | sed 's/^/|/g' >> ${TEMP_FILE2} ##在前面加入'|'作为边框再输出单词解释,重定向到第二个临时文件
echo "$_DIV" >> ${TEMP_FILE2} ##输出边框,重定向到第二个临时文件
if [ $END_LINE_1 -ne $END_LINE_2 ];then ##如果简短解释行号和结尾行号不相等,说明单词有详细解释
DETAIL=0 ##DETAIL的值置0(此刻,我第二次想到林志玲)
END_LINE_1=$((${END_LINE_1}+2)) ##再多取上面两行,不时白就看看网页咯
LINES_2=$(($END_LINE_2-$END_LINE_1)) ##详细解释共有这么多行
echo "关于 ${WORD} 的详细解释:" | sed 's/^/|/g' >> ${TEMP_FILE2}
cat ${TEMP_FILE1} | head -n ${END_LINE_2} | tail -n ${LINES_2} | sed 's/^/|/g' >> ${TEMP_FILE2} ##在前面加入'|'作为边框再输出单词解释,重定向到第二个临时文件
echo "$_DIV" >> ${TEMP_FILE2} ##输出边框,重定向到第二个临时文件
fi
cat -n ${TEMP_FILE2} | head -n $((${LINES_1}+4)) ##从第二个临时文件,输出简短解释
[ $DETAIL == 0 ] && msg_ques "\n[Y/y]\t显示更详细的解释\n"
[ $_NOW = 1 ] || msg_ques "[N/n]\t查找下一个单词\n"
msg_ques "[Q/q]\t退出程序\n[Enter]\t继续:" && read ynd
[ $_NOW == 1 ] && [ $ynd == n -o $ynd == N ] && ynd=x
[ -z $ynd ] && ynd=x ##若没有输入,置ynd为x
if [ $ynd == N -o $ynd == n ]; then
return ##返回查找下一个单词
elif [ $ynd == Q -o $ynd == q ]; then
exit_proc ##退出程序
elif [ $ynd == Y -o $ynd == y ]; then ##显示详细解释
cat -n ${TEMP_FILE2} | less
msg_info "`cat -n ${TEMP_FILE2}`"
msg_ques "\n\n是否把以上单词加入生词本?\n[A/a]\t加入全部解释\n[Y/y]\t加入简短解释\n[Q/q]\t退出程序\n[Enter]\t继续:"
read yn1
else
msg_ques "\n\n是否把以上单词加入生词本?\n[Y/y]\t加入生词本\n[Q/q]\t退出程序\n[Enter]\t继续:"
read yn1
fi
[ -z $yn1 ] && yn1=x
if [ $yn1 == Q -o $yn1 == q ]; then
exit_proc ##退出程序
elif [ $yn1 == Y -o $yn1 == y ]; then
[ -e ${DICT} ] && chmod 644 ${DICT} ##加入生词本之前,打开生词本的写权限
cat ${TEMP_FILE2} | head -n $((${LINES_1}+4)) >> ${DICT} ##把简短解释重定向到生词本
msg_warn "\n以上单词的简短解释已经入生词本\n"
elif [ $yn1 == A -o $yn1 == a ]; then
[ -e ${DICT} ] && chmod 644 ${DICT}
cat ${TEMP_FILE2} >> ${DICT} ##把详细解释重定向到生词本
msg_warn "\n以上单词的详细解释已经入生词本\n"
else
msg_warn "\n果断放弃此单词\n"
fi
rm -rf ${TEMP_FILE2}
return
}
not_found ()
{
msg_erro "\n*\t抱歉,${WORD}没有找到!\n"
grep "您要找的是不是" ${TEMP_FILE1} > /dev/null 2>&1
[ $? == 0 ] && grep "您要找的是不是" ${TEMP_FILE1}
return
}
exit_proc ()
{
[ -e ${TEMP_FILE1} ] && rm -rf ${TEMP_FILE1} ##删除临时文件
[ -e ${TEMP_FILE2} ] && rm -rf ${TEMP_FILE2}
exit
}
###主程序从这里开始
if [ $# -ne 0 ];then ##参数是否为空
for WORD in "$@" ##循环取参数
do
TEMP_FILE1=`mktemp` ##在/tmp下生成一个临时文件,用来存放整个网页的内容
msg_warn "正在为你查找单词:" ##提示信息,告知用户查找正在进行
msg_erro "${WORD} " ##以红色突出显示当前查找的单词
##下面这行用w3m下载网页,重定向到第一个临时文件,因为各种因素,不可能立即返回结果,所以在后台运行
w3m -no-cookie -dump "http://${URL}/search?q=${WORD}&ue=utf8&keyfrom=dict.index" | grep -v ^$ > ${TEMP_FILE1} &
until [ -s ${TEMP_FILE1} ] ##循环输出 ........
do
msg_warn '.'
sleep 0.25 ##每间隔0.25秒就输出一个.
done
echo ##输出一个行空行
grep "英汉释义.*我要报错" ${TEMP_FILE1} > /dev/null 2>&1 ##匹配这几个字
if [ $? == 0 ]; then
found ##如果查找到上面那几个字,则说明查找到单词,调用found()函数
else
not_found ##否则没有找到,调用not_found()函数
fi
rm -rf ${TEMP_FILE1} ##完成了一次单词查找,删除第一个临时文件
_NOW=$((_NOW-1)) ##单词数量减1
done
if [ $yn1 == A -o $yn1 == a -o $yn1 == Y -o $yn1 == y ];then
echo "###以上生词加入于`date +'%Y/%m/%d %T'`" >> ${DICT}
msg_info "###以上生词加入于`date +'%Y/%m/%d %T'`\n"
fi
[ -e ${DICT} ] && chmod 444 ${DICT}
else
msg_erro "* Usage:\tdict.sh WORD [WORD1] [WORD2] [...]\n"
msg_erro "\n* 说明:\t本程序仅接受阿拉伯数字和英文单词\n\t\t如果要支持词组,请给词组加上引号\n"
msg_erro "* "
for MSG in 特 别 说 明 : "\t" 本 产 品 选 料 上 乘 , 造 工 巧 究 , 低 碳 环 保 , 无 需 在 冷 藏 , 不 含 毒 副 作 用 , 人 畜 无 害 , 可 适 用 范 围 极 广 "\n" "\t\t" 不 分 男 女 , 老 少 咸 宜 , 无 论 是 适 龄 未 婚 男 女 青 年 、 有 妇 之 夫 、 有 夫 之 妇 , 还 是 鳏 夫 、 寡 妇 都 可 放 心 使 用 "\n" "\t\t" 未 成 年 少 男 少 女 无 需 家 长 陪 同 就 可 放 心使 用 , 确 实 是 难 得 一 见 的 好 产 品 。 "\n" "\t\t" 奥 巴 马 用 了 都 说 : “ 真 是 V e r y G o o d !” "\n"
do
msg_erro $MSG
sleep 0.05
done
#exit_proc
fi
exit