正则表示法解惑(具体例子请教高手)

发表于:2007-07-04来源:作者:点击数: 标签:
今天看到一个小script是利用sed的RE现实IP的内容如下: #!/bin/sed-f /^[^]/!d N s/^\([^]*\).*\n.*addr:\([^]*\).*/\1\2/ 执行的时候打/sbin/ifconfig|./scripts 就能只显示出device和IP。 问题是我看了一下发现不是看的很懂,不知道有没有RE熟悉的高手给我

今天看到一个小script是利用sed的RE现实IP的内容如下:
#!/bin/sed -f
/^[^ ]/!d
N
s/^\([^ ]*\).*\n.*addr:\([^ ]*\).*/\1 \2/
执行的时候打/sbin/ifconfig | ./scripts
就能只显示出device和IP。

问题是我看了一下发现不是看的很懂,不知道有没有RE熟悉的高手给我指教一二啊感激不尽啊,我说一下我愚顿的理解:
/^[^ ]/!d      --意思是不是行开头为非空的不删除,就是删除行开头为空的。
N                  --不理解啊,高手指教了。
s/^\([^ ]*\).* --我好像知道\ (\)包括的内容对应后面的\1这里是不是表示开头为非空的部分
\n                  --这个什么意思啊?不理解了难道就是回车空行???
.*addr:\([^ ]*\).*--我认为这个是表示addr有addr:后面的直到非空的东西都包括在\(\)里面与\2对应,但是后面又有的.*是什么意思啊
/\1\2/           --这个东西我知道就是按找前面排的\1\2替换现实并且是非(\g的)全部替换。

我是这样理解的不知道有没有错,三行怎么窜起来理解乃,我认为第一行没什么用啊但是我去除第一行就起不到作用。希望高手出来指点一下啊大家也顺便讨论下啊我认为RE这个东西蛮有意思的啊^_^
附:本来ifconfig结果为:
eth0      Link encap:Ethernet  HWaddr 00:02:B3:4F:F6:FE  
          inet addr:X.X.X.X   Bcast:61.129.74.255。。。。。

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0。。。。。

执行/sbin/ifconfig | ./scripts后的结果为
[root@GK_SH tmp]# ifconfig | ./test
eth0 X.X.X.X
lo 127.0.0.1

 :D

 VO小新 回复于:2004-01-22 13:40:24
:shock:  :em06: 怎么都一天了都没有人出来指点下啊,看的有20来人次了,肯出手的一个没有啊,大家知道多少指教多少啊,共享一下啊。

 q1208c 回复于:2004-01-22 20:23:54
我这没有Linux 的机器,你可以一行行试试。
我觉得第一行是处理空格的,第二行是把输出的再读回去,第三行才是找出 Device 和 IP address 的。我现在没法试,以后试试看。

 VO小新 回复于:2004-01-24 12:14:51
问题不对啊,第一行单独执行的结果就是列出ifconfig的第一行,但是我认为第三行已经把前面要做的事情都做了啊,但是我单独执行第三行就是不行的说,有没有人懂RE的啊?出来指教下啊,不是那么大的论坛没人懂吧,汗~~~ :em06:

 Chuai 回复于:2004-01-24 13:57:38
第一行:
/^[^ ]/!d
需要注意方括号中有一个空格,是用来将ifconfig输出中所有以空格开始的行删除使用的,这样就保留了所有非空格开始的行,也就是设备名称所在的行,如:
eth0 Link...........

第二行:
N 在sed命令中是做如下解释的:
Read/Append the next line of input into patten space
也就是当/^[^ ]/!d读到第一个非空格开头的行后,读下一行,而在下一行正好是地址所在的行

第三行:
s/^\([^ ]*\).*\n.*addr:\([^ ]*\).*/\1 \2/ 
把它分解一下可以变成三部分:
第一部分是s/,用于替换的意思
第二部分是^\([^ ]*\).*\n.*addr:\([^ ]*\).*
第三部分是\1 \2
其中第三部分的\1是指第二部分的[^ ]* 这部分内容,由于()有特殊性,所以用\转义了,实际内容就是[^ ]*,而这一部分和第一步的那个类似,不过是选取了非空格开头的第一个单词,也就是网卡的名字,如eth0,\n是指回车,接下来的addr:很容易理解了,就是选取地址然后打印出来喽

 Chuai 回复于:2004-01-24 13:59:57
另外,第三行完全是为后面两行打基础的,将过滤出来的两行传递给了第三行进行继续处理

 VO小新 回复于:2004-01-25 21:57:35
[quote:f1dceb724a="Chuai"]这一部分和第一步的那个类似,不过是选取了非空格开头的第一个单词,也就是网卡的名字,如eth0,\n是指回车,接下来的addr:很容易理解了,就是选取地址然后打印出来喽[/quote:f1dceb724a]

哇高手终于肯出手了,首先表示道歉:由于过年到处走动致使没能及时回复您的帖子。
接着提出疑问:您说的我大致理解了,很受用。但是对于一些细节我还是不是很明了,比如您说的
  “其中第三部分的\1是指第二部分的[^ ]* 这部分内容,由于()有特殊性,所以用\转义了,实际内容就是[^ ]*,而这一部分和第一步的那个类似,不过是选取了非空格开头的第一个单词,也就是网卡的名字,如eth0,\n是指回车”
   我的理解是由于第一行与第二行已经将要处理的内容传递给了第三行处理也就是说第三行处理的应该是“eth0      Link encap:Ethernet  HWaddr 00:D0:4C:BF:93:19”下面的那一行也就是“inet addr:192.168.0.100  Bcast:192.168.0.255  ........",我的问题是那么\1取到的部分应该是"inet"才对啊"eth0'他是从哪里取到的啊script的第一行与第二行”/^[^ ]/!d 
N " 不就是个传递的作用吗。还有\n回车在这里是什么作用乃?非要使用吗?
再次感谢您的回答 :P 

ps:附上ifconfig后eth0的内容您讲解起来方便点

eth0      Link encap:Ethernet  HWaddr 00:D0:4C:BF:93:19
          inet addr:192.168.0.100  Bcast:192.168.0.255  ........
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1084 errors:0 dropped:0 overruns:0 frame:0
          TX packets:856 errors:0 dropped:0 overruns:0 carrier:0
          collisions:2 txqueuelen:100
          RX bytes:84292 (82.3 Kb)  TX bytes:86213 (84.1 Kb)
          Interrupt:11 Base address:0x7000

 Chuai 回复于:2004-01-27 10:14:29
[quote:69930d7921="VO小新"]
N " 不就是个传递的作用吗。还有\n回车在这里是什么作用乃?非要使用吗?
再次感谢您的回答 :P 

ps:附上ifconfig后eth0的内容您讲解起来方便点

eth0      Link encap:Ethernet  HWaddr 00:D0:4C:BF:93:19
..........[/quote:69930d7921]

没错,是传递的
eth0 Link encap:Ethernet HWaddr 00:D0:4C:BF:93:19 
inet addr:192.168.0.100 Bcast:192.168.0.255 ........ 
给第三行
而1和2对应的分别是括号内的东西
所以1对应的是第一行的eth0,然后一个回车后
对应2的就是IP地址了

 VO小新 回复于:2004-01-29 18:32:13
哦~~~!!!!是将前面2行都传过去啊 这次彻底了解了。大论坛就是好啊 藏龙卧虎的。呵呵 谢谢各位高手拉! :P  8)

 VO小新 回复于:2004-01-29 18:33:24
特别是chuai,感谢感谢啊!!!

 zleil 回复于:2005-05-06 14:21:36
更正: 
          \n指的是换行,不是回车,16进制码为0x0a

原文转自:http://www.ltesting.net