从一条变态命令谈几个常见unix工具的用法。

从一条变态命令谈几个常见unix工具的用法。
FlyDragon http://www.cnfreeos.org
在开头之前,向大家介绍本书《UNIX和SHELL程序设计权威教程》,是一本国外计算机科学的经典教材,我从这

里学到了不少有趣的东西,希望学习系统管理的朋友也看看。(非广告,只是我个人认为不错)

  下面的命令不是最简单的方法,放在这里是为了向大家介绍几个常见的工具的一些用法。希望能
激起大家的灵感,想出更巧妙的方法来解决身边的问题,我不大懂shell说错的地方请大家不要吝惜砖头
酒瓶。

 grep -v ^$ a.txt|awk '{print $1}'|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 $1}'
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表示
取出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-/3-/2/' 1.txt
会帮助你把它格式化成这个形式:
123-890-4567
123-890-4567

这个命令为我们展示了sed的一个替代命令s 的基本用法:
 s/模式/替换物/
再看上面的命令
s//([0-9]/{3/}/)/([0-9]/{4/}/)/([0-9]/{3/}/)//1-/2-/3/
虽然很长,但根据我们刚才学过的知识,不难拆开它。
/([0-9]/{3/}/)/([0-9]/{4/}/)/([0-9]/{3/}/) 这个串表达了一个RE,并保存到了3个缓冲区里。
/([0-9]/{3/}/)描述了这样一个序列“精确重复3次的由0-9中之一字符,也就是一个3个数字组成的序列”
我们看后面的替换物,这个是由缓冲区取出并重新组成的串。
/1-/3-/2 由缓冲区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也是一个过滤器,它删除重复的行。
终于敲完了,好累,希望能对大家有点用处。
本页使用vim编辑

另一种方法是可以用 pf 的 reply-to/route-to 配合 table 来做。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值