Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103068348
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-04-19 22:39:57

作者:lg   来自:

grep -v ^$ a.txt|awk '{print }'|cut -f1-3 -d . |sed 's/^.*$/route add \-net &\.0 192\.168\.0\.1/' |uniq

有这么样一个平板文件a.txt:
60.48.0.0    - 60.54.255.255  马来西亚         电信
60.160.0.0   - 60.160.223.255 云南省          电信
60.160.224.0  - 60.160.225.255 云南省          文山州电信
60.160.226.0  - 60.161.255.255 云南省          电信
60.162.0.0   - 60.162.0.255  浙江省台州市       路桥区电信ADSL
60.162.1.0   - 60.162.51.255  浙江省          电信
60.162.52.0   - 60.162.52.255  浙江省临海市       电信
60.162.53.0   - 60.162.79.255  浙江省          电信

60.162.80.0   - 60.162.91.255  浙江省台州市       (天台)电信
60.162.92.0   - 60.162.127.255 浙江省台州市       电信
60.162.128.0  - 60.163.0.255  浙江省          电信


60.163.1.0   - 60.163.1.255  浙江省嘉兴市       电信
60.163.2.0   - 60.163.4.255  浙江省          电信
60.163.5.0   - 60.163.5.255  浙江省嘉兴市       电信
60.163.6.0   - 60.163.13.255  浙江省          电信
61.128.252.77  - 61.128.252.77  重庆市永川        电信非住宅宽带用户
61.128.252.79  - 61.128.252.79  重庆市永川        电信非住宅宽带用户
61.128.252.83  - 61.128.252.83  重庆市永川        电信非住宅宽带用户
61.128.252.85  - 61.128.252.85  重庆市永川        电信非住宅宽带用户
61.128.252.92  - 61.128.252.92  重庆市永川        电信非住宅宽带用户
61.128.252.94  - 61.128.252.94  重庆市永川        电信非住宅宽带用户
61.128.252.96  - 61.128.252.96  重庆市永川        电信非住宅宽带用户
简单说明下,这个是freebsdchina论坛中热心网友share出来的一些地区的ip列表,好让大家做策略路由,根据目
标网络的服务商来选择路径,访问电信的ip走电信的线,访问网通的ip走网通的线。
上面的文件中的ip. 都是一些电信服务商的,也就是说希望把这些ip段做成n条静态路由,需要类似这样的命令来完成:
route add -net 60.48.0.0 192.168.0.1
route add -net 60.160.224.0 192.168.0.1
........
下面我们一步步来看看那一长串命令都做了什么。
grep -v ^$ a.txt
grep 是比较经典的命令之一,他表示“全局正则表达式打印(Global regular expression print),是一个程序家族,
它可以对输入文件中匹配指定正则表达式的所有行进行搜索,并把输出写到标准输出文件(显示器).
(正则表达式格式参见man 7 re_format),

它的命令格式是:
grep 选项 正则表达式 文件列表
常见的选项有下面几个:
-i忽略大小写
-n打印行号
-v打印不匹配行(排除RE)
-f file表达式在文件中
上面的命令,参数是 -v 正则表达式是 " ^$ " 也就是空行,通过这个命令我们就排除了中间的几个空行



|是一个管道操作符号,管道在UNIX系统里很常用,管道会将一个命令的输出保存到临时缓冲区,然后缓冲区的
内容被做为下一个命令的输入,管道有一个使用要求,就是前面的命令必须能发送输出到标准输出设备,后面
的命令必须能从标准输入设备读入需要的输入。由于种种特性,管道通常是避免创建中间文件的手段。


awk '{print }'
awk名字来自它的创始人(Alfred V.Aho、Perter J.Weinberger和Brian W.Kernighan),相比其他工具来说它有
点强大过分了。没错,它本来就是一个伪装成使用程序的编程语言。awk和sed工作类似,它从输入文件中逐行
读入,并整行或部分执行一个动作。但和sed不同,除非你明确指定,awk不会打印行。
正如刚才所说,awk太强大了,包含了诸如数组,函数,流程等其他工具所不支持的特性,我们就不打算在
这里多说awk,学习awk有本不错的书籍OReilly的sed & awk.回过头来,刚才的命令是awk才shell程序里比较
典型的一个“列打印”,awk把文件看成字段和记录的集合,awk约定使用一个或多个空格或用户定义的其他字
符来分割字段,同时,awk把每行都看成一个记录,所以刚才的命令,替我们从上次的结果中抽取出第一列,ip
地址部分。

管道操作符继续把我们的输出定向到下面的输入。

cut -f1-3 -d . (注意后面有个点)
cut是一个过滤器命令,它和paste属于一个类型的命令,cut从文件中删除列,paste连接列
它的命令格式是:
cut 选项 文件列表
常见的选项有-c(指定字符位置),-f指定区域,-d重新定义分割符号,-s行内没有分割符的时候抑制输出。
经过2次的操作,我们的ip地址文件已经边的仅剩下一列了:
60.160.224.0
...
60.163.2.0
...
61.128.252.96
我们的cut命令,-d指定了用点做分割符,划分出一块块的区域来,同时我们用-f来指定输出区域1到3的内容。
也就是去掉了ip地址的最后面一段,我们这样做是为了把其中有些不是网络的ip转换成ip。其实这样已经够了
,不做后面的sed操作也可以在路由中表示网络。但我们还是来个画蛇添足,借此熟悉下正则表达式的命令的:
保存、向后引用、重复、锚、点,缓冲区等知识,以及sed的基本替代,和原子替换操作。
正则表达式是UNIX比其他操作系统方便都理由之一,它太cool了,高效的表达字符串的方法,是高手为之骄傲
的本钱,乱遭遭的字符序列,却是让初学者和外行迷惑,甚至不寒而栗。熟悉并使用正则表达式,需要你做很
多的实践并要锻炼自己的小聪明和偷懒习惯。
由于篇幅有限,我们不深入讲解,未尽兴的地方请读者自己 man re_format.
我们从sed支持的正则表达式说起,sed支持正则表达式的字符、点、类、锚、序列、向后引用、重复和保存

单字符,点,类,锚和向后引用组成了正则表达式的原子,原子用来匹配文本的内容,并发现文本的位置。

字符,很容易理解,任何一个单字符就是一个最简单的RE,它匹配这个确定的字符。

点 ,就是一个英文标点的句号,他匹配除\n外的任何单字,它的范围这么大,以至于他自己本身并不能做什么
,但当它和其他元素结合起来就可以发挥出强大的表达能力,大家不难理解a.b可以代替aab、abb,acb,a2b.....

类,定义了一个Ascii集合,只要集合中的一个元素匹配了文本,那么这块文本就满足了这个集合型的RE,就是
说[abc]这个集合包含a,b,c三者,三个字符都满足这个RE,类中,还有常见2个符号,一个是破折号“-”用来
表示连续空间,比如[a-z]、[A-Z]、[0-9]等,另一个是 非“ ^ ”用来表示余集 ,比如[^aeiou]表示任意非元
音字符

锚,一般用来做对齐用,只有4种锚 ^表示行首,$行尾,\<单词开头,\>单词结尾,注意,锚匹配的是对齐,也
就是不可见的,一般用来和其他原子联合使用 ,^A(以大写字母A开头),8$以数字8结尾,e\>以e结尾的单词



向后引用,可以把文本保存在9个缓冲区中,留做以后用,向后引用提供了取出缓冲区文本的方法。使用向后引
用之前需要先“保存”,一会我们要讲。向后引用使用转义字符\和1到9,这9个数字结合使用。比如表示
取出2号和3号缓冲区内容。
为了让RE更强大,可以把原子和运算符结合起来。正则表达式有序列、替换、重复、组、保存共5种运算符。

序列,是一个空运算符,表示在出现原子系列的地方,如字符序列abc、或a4s2,他们中间都隐含一个序列运算
符.

重复,是转移括号\{m,n\}的集合,它包含2个数字m和n,由逗号分开,m表示至少,n表示至多,当然也可以只
剩一个数字,或一个数字一个逗号,如\{3\}重复3次,\{3,6\}重复3到6次,\{3,\}不少于3次,聪明的你可能
立即想到\{,4\}表示最多4次,没错,就是这么简单。

保存,这个操作可以把文本放到9个缓冲区中,它的符号是\(...\)两个转义括号中间放置需要保存的内容,依
照顺序,第一个被保存的文本就会被放置到缓冲区1,依次类推。

为了简化RE ,有一些特殊形式的缩写运算符号,比如*匹配前面的原子一次或多次,?匹配前面的原子0次或1次

假设文件1.txt中有下面内容
1234567890
1234567890
那么下面这个长长的命令
sed 's/\([0-9]\{3\}\)\([0-9]\{4\}\)\([0-9]\{3\}\)/--/' 1.txt
会帮助你把它格式化成这个形式:
123-890-4567
123-890-4567

这个命令为我们展示了sed的一个替代命令s 的基本用法:
s/模式/替换物/
再看上面的命令
s/\([0-9]\{3\}\)\([0-9]\{4\}\)\([0-9]\{3\}\)/--/
虽然很长,但根据我们刚才学过的知识,不难拆开它。
\([0-9]\{3\}\)\([0-9]\{4\}\)\([0-9]\{3\}\) 这个串表达了一个RE,并保存到了3个缓冲区里。
\([0-9]\{3\}\)描述了这样一个序列“精确重复3次的由0-9中之一字符,也就是一个3个数字组成的序列”
我们看后面的替换物,这个是由缓冲区取出并重新组成的串。
-- 由缓冲区1加个-然后紧跟缓冲区3再加-再跟缓冲区2,三个缓冲区重新组合后就是新的替换用序列。

我们回头在来看看我们开头所说的命令:
sed 's/^.*$/route add \-net &\.0 192\.168\.0\.1/'
这个也是一个重新格式化,和替换的例子。&操作符号将代表前面的“模式”在这里代表 ^.*$也就是所有的行
。在替换物当中,一些特殊的字符,需要使用转义符号\来屏蔽原来的含义。
上面的命令以理解为:“在每一个ip地址开头加 "route add -net "然后紧跟这个ip地址,最后以192.168.0.1
结尾。于是就满足了

route add -net 60.48.0.0 192.168.0.1
route add -net 60.160.224.0 192.168.0.1
这样的命令格式

仔细看下下现在的输出,你可能发好多重复的行,这些是由一些固定的ip而非网络被过滤后的结果,我们可以
用uniq消除它,uniq也是一个过滤器,它删除重复的行。
终于敲完了,好累,希望能对大家有点用处。
阅读(501) | 评论(0) | 转发(0) |
0

上一篇:dd 命令的用法

下一篇:一个关于awk的实例

给主人留下些什么吧!~~