Chinaunix首页 | 论坛 | 博客
  • 博客访问: 45359
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2015-11-16 18:43
文章分类

全部博文(14)

文章存档

2016年(6)

2015年(8)

我的朋友

分类: LINUX

2015-12-25 15:29:37

本文是学生博主,于chinaunix论坛中对大神答案的分析得到的一个总结(侵删)。

原帖(包含shell,python,perl,awk解法):


下面分析一条命令,通过分析此命令加深对:label,t,b命令的理解。

一、命令
echo {3..14}|sed -nr 'h;:a;/(\w+\s){4}/p;s/\s\w+$//;ta;g;s/\w+\s//;h;/\s/ba'

二、命令输出
3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13
3 4 5 6 7 8 9 10 11 12
3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10
3 4 5 6 7 8 9
3 4 5 6 7 8
3 4 5 6 7
4 5 6 7 8 9 10 11 12 13 14
4 5 6 7 8 9 10 11 12 13
4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11
4 5 6 7 8 9 10
4 5 6 7 8 9
4 5 6 7 8
5 6 7 8 9 10 11 12 13 14
5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 11 12
5 6 7 8 9 10 11
5 6 7 8 9 10
5 6 7 8 9
6 7 8 9 10 11 12 13 14
6 7 8 9 10 11 12 13
6 7 8 9 10 11 12
6 7 8 9 10 11
6 7 8 9 10
7 8 9 10 11 12 13 14
7 8 9 10 11 12 13
7 8 9 10 11 12
7 8 9 10 11
8 9 10 11 12 13 14
8 9 10 11 12 13
8 9 10 11 12
9 10 11 12 13 14
9 10 11 12 13
10 11 12 13 14


三、分析脚本:


echo {3..14} | 
sed -nr '
h;
:a;
/(\w+\s){4}/p;
s/\s\w+$//;
ta;
g;
s/\w+\s//;
h;
/\s/ba'


-n 静默,不自动输出模式空间
-r 支持正则表达式匹配替换项
\w 任意字符
\s 空格

(一)内循环分析:
echo {3..14}|sed -nr 'h;:a;/(\w+\s){4}/p;s/\s\w+$//;ta;'
3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13
3 4 5 6 7 8 9 10 11 12
3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10
3 4 5 6 7 8 9
3 4 5 6 7 8
3 4 5 6 7

执行过程:
1.给 3 .. 14 打上了标签a,打印,然后执行s/ \w+$//替换掉最后的“ 14”,由于-n选项不会输出替换后的 3 .. 13
2.执行ta是跳转到标签a位置循环执行命令,此时这一行为 3 .. 13 执行p打印出来(打印第二行3 .. 13),然后s再替换掉“ 13”#-n选项静默,替换后没有自动打印[1]
3.再跳转到行首,打印(结果为 3 .. 12)再s替换“ 12” ...
4.循环步骤1-3,最后只剩下4个“数字+空格”,不满足/(\w+\s){4}/p,不再打印,继续执行剩下内容s/\s\w+$//;ta;直至替换行至空,结束命令[2]


注:
[1]
a.插入p输出模式空间
$ echo {3..14}|sed -nr 'h;:a;/(\w+\s){4}/p;s/\s\w+$//;p'
3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13
b.没有-n选项自动打印模式空间内容
$ echo {3..14}|sed -r 'h;:a;/(\w+\s){4}/p;s/\s\w+$//;'
3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13


[2]
若没有/(\w+\s){4}/p匹配,只有p将一直打印
$ echo {3..14}|sed -nr 'h;:a;p;s/\s\w+$//;ta;'
3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13
3 4 5 6 7 8 9 10 11 12
3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10
3 4 5 6 7 8 9
3 4 5 6 7 8
3 4 5 6 7
3 4 5 6
3 4 5
3 4
3


(二)外循环分析:

(1)删除最后的/\s/ba,替换为p(打印)
$ echo {3..14}|sed -nr 'h;:a;/(\w+\s){4}/p;s/\s\w+$//;ta;g;s/\w+\s//;h;p'
3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13
3 4 5 6 7 8 9 10 11 12
3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10
3 4 5 6 7 8 9
3 4 5 6 7 8
3 4 5 6 7
4 5 6 7 8 9 10 11 12 13 14


1.执行内循环 #h;:a;/(\w+\s){4}/p;s/\s\w+$//;ta;
2.执行完内循环后 g;s/\w+\s//;h;
g #将保持空间内容替换到掉模式空间,此时模式空间为3..14
s/\w+\s// #将第一个“数字+空格”删除
h #将模式空间保持并替换保持空间(用于下一外循环)
3.p打印模式空间4..14
4.若p改为/\s/ba(即原命令)则重新开始内循环[3],重复1-3(外循环),直至输出最后一行“10 11 12 13 14”,但是命令还在继续只不过不再打印[4]



[3]:a标签标注什么?
:a标注的是命令的这个位置,而不是模式空间

例子:使用两行,并且插入n命令
$ echo -e "3 4 5 6 7 8 9 10 11 12 13 14\na b c d e" |sed -nr 'h;n;:a;/(\w+\s){4}/p;s/\s\w+$//;ta;g;s/\w+\s//;h;/\s/ba'
a b c d e  #注意第一行输出为"a b c d e"
4 5 6 7 8 9 10 11 12 13 14 #注意第一个数字是4而不是3
4 5 6 7 8 9 10 11 12 13
4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11
4 5 6 7 8 9 10
4 5 6 7 8 9
4 5 6 7 8
5 6 7 8 9 10 11 12 13 14
5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 11 12
5 6 7 8 9 10 11
5 6 7 8 9 10
5 6 7 8 9
6 7 8 9 10 11 12 13 14
6 7 8 9 10 11 12 13
6 7 8 9 10 11 12
6 7 8 9 10 11
6 7 8 9 10
7 8 9 10 11 12 13 14
7 8 9 10 11 12 13
7 8 9 10 11 12
7 8 9 10 11
8 9 10 11 12 13 14
8 9 10 11 12 13
8 9 10 11 12
9 10 11 12 13 14
9 10 11 12 13
10 11 12 13 14
解释:
第一步,第一个h将"3..14"保存到保持空间
第二步,执行n将输入下一行而不返回脚本顶部(即n之前的命令h不会对"a b c d e"生效),然后执行:a打印标签a.
第三步,执行内循环(打印"a b c d e")
第四步,g将保持空间内容替换模式空间,此时模式空间为"3..14",s/\w+\s//;h删除第一个“数字+空格”即“4..14",并将“4..14”替换掉保持空间的内容.
第五步,执行/\s/ba,跳转到a处循环执行命令,直至结束


[4]在命令最后插入p,打印最后的模式空间为“14"
$ echo {3..14}|sed -nr 'h;:a;/(\w+\s){4}/p;s/\s\w+$//;ta;g;s/\w+\s//;h;/\s/ba;p'
3 4 5 6 7 8 9 10 11 12 13 14
3 4 5 6 7 8 9 10 11 12 13
3 4 5 6 7 8 9 10 11 12
3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10
3 4 5 6 7 8 9
3 4 5 6 7 8
3 4 5 6 7
4 5 6 7 8 9 10 11 12 13 14
4 5 6 7 8 9 10 11 12 13
4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11
4 5 6 7 8 9 10
4 5 6 7 8 9
4 5 6 7 8
5 6 7 8 9 10 11 12 13 14
5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 11 12
5 6 7 8 9 10 11
5 6 7 8 9 10
5 6 7 8 9
6 7 8 9 10 11 12 13 14
6 7 8 9 10 11 12 13
6 7 8 9 10 11 12
6 7 8 9 10 11
6 7 8 9 10
7 8 9 10 11 12 13 14
7 8 9 10 11 12 13
7 8 9 10 11 12
7 8 9 10 11
8 9 10 11 12 13 14
8 9 10 11 12 13
8 9 10 11 12
9 10 11 12 13 14
9 10 11 12 13
10 11 12 13 14
14
阅读(1358) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~