文档章节

shell脚本处女作之命令行词典

laichendong
 laichendong
发布于 2014/06/25 09:27
字数 1018
阅读 61
收藏 1
ubuntu下没有一个用着趁手的客户端版词典,查词又作为刚需摆在那里。搜了一下,有人用python和shell写过一些脚本调用web把查词结果显示到命令行,成为“命令行词典”。很有geek范儿。我喜欢“柯林斯词典”的英-英释义,还有例句。现成的那些脚本都没有采纳这个词典。就自己动手,丰衣足食了。作为一个基本上的shell盲来说,这么一个小程序,也很长姿势。 原理很简单。 抓取有道词典相应词语页面的内容。用awk,sed处理截取想要的内容,最后在用自己想要的形式输出出来

一、抓取页面

我使用cur抓取了有道词典的 单词页面
curl -s 'http://dict.youdao.com/search?q='$1''
(-s 参数表示“silence”,安静模式,不会输入多余的信息) 分析页面的源代码发现,如果所查的词有柯林斯词典的解释,将会出现在下面: 20130826195620

二、从源码中截取有用的信息

awk 'BEGIN{j=0;} {if(/collinsToggle/){ j++;} if(j==1) {print $0; if(/<\/ul>/) j=0;}}' | sed 's/<[^>]*>//g' | sed 's/&nbsp;//g'| sed 's/&rarr;//g' | sed 's/^\s*//g' | sed '/^$/d'
这里分了几步来做,首先使用awk找出柯林斯词典的内容,然后用sed移除掉html代码中的标签,空白,空行等等,剩下的就是我们要的“干货“了。关于awk和sed的内容,照着耗子的 AWK简明教程sed简明教程做了几遍,加上一些google就搞定了。感觉awk简直是map-reduce思想的开山鼻祖啊。

三、输出

其实直接就将上面命令的内容输出,功能就已经ok了。勉强也能看。但作为geek又岂能让自己的”第一次“如此丑陋?于是我将命令的输出重定向到一个文件里,然后用read将文件按行读入稍作加工。关于将文件按行读入,也遇到一个小坑。开始我是用的是这个方法读取的文件:
head=''
cat /etc/passwd | while read LINE  
do
        head="$head $LINE"
        echo $LINE 
done
然后发现在循环结束后head并没有改变,然后google到了这篇 帖子,又涨了点姿势。于是我将读取文件的代码稍作了一下修改:
while read line
do
	# do something
done < $TEM_FILE
最后为了美观。想对输出的内容做一点颜色上的调整,突出一下重点。于是又google。发现命令行可用用ANSI颜色来控制文本的样式(用SecureCRT的时候也可以找到这个选项,勾上就有颜色了)。关于ANSI颜色,又 google了一些文章看看就明白了:) 把完整代码贴一下:
#!/bin/bash
ARGS=1
E_BADARGS=65
TEM_FILE="/tmp/dict.tmp"

if [ $# -ne "$ARGS" ]
 then
	echo "Usage:`basename $0` word"
	exit $E_BADARGS
fi

# 抓取页面,删除html代码,空行等,只留下想要的内容
curl -s 'http://dict.youdao.com/search?q='$1'' | awk 'BEGIN{j=0;i=0;} {if(/phrsListTab/){i++;} if(i==1){print $0; if(/<\/ul>/){i=0;}} if(/collinsToggle/){ j++;} if(j==1) {print $0; if(/<\/ul>/){j=0;}}}' | sed 's/<[^>]*>//g' | sed 's/&nbsp;//g'| sed 's/&rarr;//g' | sed 's/^\s*//g' | sed '/^$/d'> $TEM_FILE

# 处理输出
is_head=true # 当前行是否属于“头部”
head="" # 头部内容
body="" # 主体内容
ln_item=0 # 每一条解释的行号
ln_eg=0 # 例句行号

while read line
do
	let ln_item++
	let ln_eg++
	num_flag=`echo "$line" | awk '/[0-9]+\.$/'`
	if [ "$num_flag" != "" ]; then ## 遇见'数字+点'开头的行
		is_head=false # 第一次遇见数字行  将头部标示设置为false
		ln_item=0
	fi

	eg_flag=`echo "$line" | awk '/例:$/'` # 遇见'例:'开头的行
	if [ "$eg_flag" != "" ]; then
		ln_eg=0
	fi

	if $is_head ; then
		head="$head $line"
	else
		if [ $ln_item == 0 ] ; then
			line="\033[32;1m\n\n$line\033[0m" # 释义编号
		elif [ $ln_item == 1 ] ; then
			line="\033[32;1m[$line]\033[0m" # 词性
		elif [ $ln_item == 2 ] ; then
			line="\033[1m$line\033[0m" # 释义 
		elif [ $ln_eg == 0 ] ; then
			line="\033[32;1m\n   $line\033[0m" # 例:
		elif [ $ln_eg == 1 ]; then
			line="\033[33m$line\033[0m" # 例句 
		elif [ $ln_eg == 2 ]; then
			line="\033[33m$line\033[0m" # 例句释义 
		fi
		body="$body $line"
	fi
done < $TEM_FILE
echo -e "\033[31;1m$head\033[0m $body"

exit 0
   

© 著作权归作者所有

共有 人打赏支持
laichendong
粉丝 8
博文 85
码字总数 71483
作品 0
朝阳
程序员
加载中

评论(1)

hehe668
hehe668
刚开始看到这个源代码,就很喜欢,想知道怎样从页面源代码中如何抓取想要的信息的,反复看了几天,渐渐对整体的框架有了了解.今天又偶遇作者的原创思路,从最初的遇到的问题(ubuntu下没有一个用着趁手的客户端版词典)到提出自己的想法,并根据自己的需求,参考相关的资料,就开始行动了,途中又不断的优化自己的代码.真得干的漂亮.为你点赞.同时感谢你的开源精神!愿大神带菜鸟一起飞!13121213
google translate between chinese and english

每次碰到不认识到单词都要请教“有道词典”,可是又不想让它常驻内存。所以考虑在cygwin下使用wordnet,但是到了cygwin17下的安装wordnet又需要安装大堆的X11,不符合我简洁的风格,所以写了...

wonder365
2013/02/19
0
2
Linux shell 编程

shell 编程概念 (1) shell是一种命令行解释器,外壳有很多种类 (2) shell 看成是Linux内核和用户沟通的桥梁,用户默认不能直接操作内核 (3)可以通过shell外壳去操作,用户指令传递给shell,传...

zdq1992
2017/11/15
0
0
Shell脚本编程学习入门:Shell编程基础

Shell脚本编程学习入门是本文要介绍的内容,我们可以使用任意一种文字编辑器,比如gedit、kedit、emacs、vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行): #!/bin/sh......

技术小阿哥
2017/11/12
0
0
调整音频模型以实现更好的语音识别

处理一个准备不充足的音频模型可能会令人感到沮丧,特别是对于语音识别领域的初学者,他们习惯使用自己的口音相关模型。不像键盘和鼠标输入那样行动相对比 较积极且易于操作系统解释,将音频...

IBMdW
2012/07/24
2K
1
面试linux运维一定会问到Shell脚本这24个问题

虽然现在Python在运维工作中已经使用很普遍,但是很多企业在找Linux云计算工程师的时候还是会问到 shell 脚本的问题,它有助于你在工作环境中自动完成很多任务。 如下是一些面试过程中,经常...

tom_tuwei
2017/12/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

nginx模块学习六 add_header 跨域访问

语法 Syntax: add_header name value [always];Default: --Context:http,server,location,if in location 例:/etc/nginx/conf.d/default.conf server {    listen       80; ......

Romanceling
今天
0
0
SpringBoot初探

#SpringBoot初探 三种创建SpringBoot项目的方式: 第一种:使用IDEA创建maven项目,选择maven-archetype-quickstart; 第二种:使用IDEA创建Spring Initializer,选择web组件; 第三种:使用...

向码而生
今天
2
0
IO

JAVA中IO技术:BIO、NIO、AIO 1、同步异步、阻塞非阻塞概念 同步和异步是针对应用程序和内核的交互而言的。 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方...

DemonsI
今天
0
0
org.apache.commons 常用工具类

一. org.apache.commons.io.IOUtils closeQuietly 关闭一个IO流、socket、或者selector且不抛出异常。通常放在finally块。 toString 转换IO流、 Uri、 byte[]为String。 copy IO流数据复制,...

sprouting
今天
0
0
linux使用Inotify监控目录或者文件状态变更

基本概念: Inotify 是一个 Linux特性,它监控文件系统操作,比如读取、写入和创建。Inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多。 需求: 1.有一个文件采集进程,...

mickelfeng
今天
0
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部