老男孩教育每日一题-第126天-通过shell脚本打印乘法口诀表
问题背景:
生成9*9乘法表
[root@oldboy ~]# seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}' 1x1=1 1x2=2 2x2=4 1x3=3 2x3=6 3x3=9 1x4=4 2x4=8 3x4=12 4x4=16 1x5=5 2x5=10 3x5=15 4x5=20 5x5=25 1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36 1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49 1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64 1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81
问题分析解决
第一步: seq 9
[root@oldboy ~]# seq 9 1 2 3 4 5 6 7 8 9
小结 为何用seq呢?
`seq' prints the numbers from FIRST to LAST by INCREMENT. By default, each number is printed on a separate line.
很容易发现seq生成的 数字每一个都是一行。
如果使用 echo {1..9} 则会在一行。无法把结果传到给sed处理。
第二步: sed ‘H;g’
[root@oldboy ~]# seq 9 | sed 'H;g' 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9
小结:
了解根据上图了解HGx用法即可。
第三步:
第一小步:
[root@oldboy scripts]# seq 9 | sed 'H;g' | awk -v RS='' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9}' 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9
小结:
1.-v 定义变量 这个变量可以在awk中使用
2.RS即 record separator
RS == “”
Records are separated by runs of blank lines. Leading and trailing newlines in a file are ignored.
每个记录(每行)被一个或多个空行分隔。文件中的换行都被忽略。
第二小步:
第一小小步
[root@oldboy scripts]# seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%d ",i)}' 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9 [root@oldboy scripts]#
改为循环输出,可是却都在一行。
小结:
printf默认不会输出换行(与print有区别)
需要手动按照条件(每个字段(record)的最后一列))输出换行”\n”
第二小小步
[root@oldboy scripts]# seq 9 | sed 'H;g' | awk ' BEGIN{ RS=""} > { > for(i=1;i<=NF;i++) > { if (i==NF) > char="\n" > else > char="\t" > printf("%d %s",i,char) > } > }' 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9
简写为
[root@oldboy scripts]# seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%d %s",i,i==NF?"\n":"\t")}' 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6 1 2 3 4 5 6 7 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9
小结:
1.exp?exp1:exp2 这是常用的条件运算符。也是最特殊的一个三目运算符。如果前面两句你不懂。记住一句话:if (condition) then-body else else-body 一样的
2.判断是否是一个字段的最后一个数 i==NF 来判断。
3.如果是最后一个则换行
4.不是则输出\t
最后一步
第一小步
配出
1*1 1*2 2*2 …………
的形式
[root@oldboy scripts]# seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%d*%d %s",i,NR,i==NF?"\n":"\t")}' 1*1 1*2 2*2 1*3 2*3 3*3 1*4 2*4 3*4 4*4 1*5 2*5 3*5 4*5 5*5 1*6 2*6 3*6 4*6 5*6 6*6 1*7 2*7 3*7 4*7 5*7 6*7 7*7 1*8 2*8 3*8 4*8 5*8 6*8 7*8 8*8 1*9 2*9 3*9 4*9 5*9 6*9 7*9 8*9 9*9
最后一小步
计算结果
[root@oldboy scripts]# seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%d*%d=%d %s",i,NR,i*NR,i==NF?"\n":"\t")}' 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
小结:
了解sed的模式空间,了解就行能看懂就行了。
awk的NR=””空的用法。
备注
今天是每日一题陪伴大家的第126天,期待你的进步。
对于题目和答案的任何疑问,请在博客评论区留言。
往期题目索引
转载于:https://blog.51cto.com/lidao/1961524