群里的讨论呵,将自个的答案发到blog上来
111110001111111011111111111100111111000011111000111111101111111111110011111100001111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111111111110011111100001111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111
seq 300|sed 's/.*//;n;s/.*//;n;s/.*//;n;s/.*//;n;n;n;n'|sed -n '1!G;$p;h'|sed 's/.*//;n;s/.*//;n;s/.*//;n;s/.*//;n;s
/.*//;n;n;n;n;n'|sed '/^$/d'|sed -n '$='
我发现自个在分析问题的时候,总是要给自己多设定条件了。使问题复杂化了
比如我那答案,事实上在考虑的时候,思维里就增加了一个条件:脚本应用于多行文件的,并分别得出每行的计算值了。
因此,我那答案在管道传输之羊,都是单行对单行的,
简单的说,在这种方法下各管道的sed,实际上可以直接合并成一个sed命令;
分开只是按思路上的分步进行处理
而sun的思路,不受这个限制的,很好的利用了管道间的行列转化呵。
于是想到的另一个解法:
perl -e 'print "0"x300;print "/n"'|sed -r 's/./a/g; s/(.{1,5})(.{0,5})//U/1/E/2/g;:a;//`/w/s//w{1,4}$//n/U&/m;//s//w{1,4}$//n&/m;ta; y/aA/n/01/x0/'
111110001111111011111111111100111111000011111000111111101111111111110011111100001111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111111111110011111100001111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111
这个是目前能想到不用管道的方法了-_-(用管道就不能体现sed的图灵完备性了呵,这里假设输入已经给出)
当然,要想得到0的数值,加管道就简单多了,当然,用管道的话,再用sed就没多少意义了,随便用grep或wc啥的
可以
perl -e 'print "0"x300;'|sed -r 's/./a/g; s/(.{1,5})(.{0,5})//U/1/E/2/g;:a;//`/w/s//w{1,4}$//n/U&/m;//s//w{1,4}$//n&/m;ta; y/aA/n//n/x0/x0/ ' |sed -n '$='
74
[root@localhost ~]# perl -e 'print "0"x300;'|sed -r 's/./a/g; s/(.{1,5})(.{0,5})//U/1/E/2/g;:a;//`/w/s//w{1,4}$//n/U&/m;//s//w{1,4}$//n&/m;ta; y/aA/n/0/x0/x0/ ' |wc -c
74
其实,sed做为图灵完备(为什么现在老把sun这句话挂面嘴里了哈?),并不需要用多个命令(通道),单sed命令完全可以搞定
[root@localhost ~]# perl -e 'print "0"x300;print "/n"'|sed -nr 's/./a/g; s/(.{1,5})(.{0,5})//U/1/E/2/g;:a;//`/w/s//w{1,4}$//n/U&/m;//s//w{1,4}$//n&/m;ta; y/aA/n/0/x0/x0/; x; s/.*/0/; G; x; :b; /./! bout; s/.//; H; g; s//n.*//g; s/^9*$/0&/; s/.9*$/x&/; H; s/.*x//; y/0123456789/1234567890/; G; s/([^/n]*)/n.*/n([^/n]*)/n.*/n([^/n]*)x.*$//3/1/n/2/; x;s/.*/n([^/n]*)/n[^/n]*//1/; bb; :out; g;s//n/ /; s/ .*//;p'
74
前半部分相同,后半部分是之前写的一个sed行字符统计脚本,带原记录的,如果不想带原记录,可以更简化
n:初始字符个数,例子中为300
l:从左边开始间隔切换的个数,这边为5
r:从右边开始间隔切换的个数,这边为4
代码:
(输出第一行为结果,第二行为0字符数和1字符数
[root@localhost sed]# awk 'BEGIN{n=300;l=5;r=4;c=0;for(i=1;i<=n;i++){k=i%(2*l);j=(n-i+1)%(2*r);if((k>=1&& k<=l)||(j>=1 && j<=r)){printf "1"}else{printf "0";c++}};print "/n"c,n-c}'
111110001111111011111111111100111111000011111000111111101111111111110011111100001111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111111111110011111100001111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111
74 226
[root@localhost sed]# awk 'BEGIN{n=100;l=5;r=4;c=0;for(i=1;i<=n;i++){k=i%(2*l);j=(n-i+1)%(2*r);if((k>=1&& k<=l)||(j>=1 && j<=r)){printf "1"}else{printf "0";c++}};print "/n"c,n-c}'
1111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111
24 76
111110001111111011111111111100111111000011111000111111101111111111110011111100001111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111111111110011111100001111100011111110111111111111001111110000111110001111111011111111111100111111000011111000111111101111