设为首页 收藏本站
查看: 710|回复: 0

Shell文本处理三剑客(三)

[复制链接]

尚未签到

发表于 2018-8-24 09:34:08 | 显示全部楼层 |阅读模式
  防伪码:锄禾日当午,汗滴禾下土。
  8.3.7 7 内置函数
  函数  描述
  int(expr)  截断为整数
  sqrt(expr)  平方根
  rand()  返回一个随机数 N,0 和 1 范围,0 < N < 1
  srand([expr])
  使用 expr 生成随机数,如果不指定,默认使用当前时间为种子,如
  果前面有种子则使用生成随机数
  asort(a, b)
  对数组 a 的值进行排序,把排序后的值存到新的数组 b 中,新排序
  的数组下标从 1 开始
  asorti(a,b)  对数组 a 的下标进行排序,同上
  sub(r, s [, t])
  对输入的记录用 s 替换 r,t 可选针对某字段替换 ,但只替换第一
  个字符串
  gsub(r,s [, t])  对输入的记录用 s 替换 r,t 可选针对某字段替换,替换所有字符串
  index(s, t)  返回 s 中字符串 t 的索引位置,0 为不存在
  length()  返回 s 的长度
  match(s, r [, a])  测试字符串 s 是否包含匹配 r 的字符串
  split(s, a [, r [,
  seps] ])
  根据分隔符 seps 将 s 分成数组 a
  substr(s, i [, n])  截取字符串 s 从 i 开始到长度 n,如果 n 没指定则是剩余部分
  tolower(str)  str 中的所有大写转换成小写
  toupper(str)  str 中的所有小写转换成大写
  systime()  当前时间戳
  strftime([format [,
  timestamp[, utc-
  flag]]])
  格式化输出时间,将时间戳转为字符串
  示例:
  1)int()
  # echo "123abc abc123 123abc123" |xargs -n1 | awk '{print int($0)}'
  123
  0
  123
  # awk 'BEGIN{print int(10/3)}'
  3
  2)sqrt()
  获取 9 的平方根:
  # awk 'BEGIN{print sqrt(9)}'
  3
  3)rand()和 srand()
  rand()并不是每次运行就是一个随机数,会一直保持一个不变:
  # awk 'BEGIN{print rand()}'
  0.237788
  当执行 srand()函数后,rand()才会发生变化,所以一般在 awk 着两个函数结合生成随机数,但是
  也有很大几率生成一样:
  # awk 'BEGIN{srand();print rand()}'
  0.31687
  如果想生成 1-10 的随机数可以这样:
  # awk 'BEGIN{srand();print int(rand()*10)}'
  4
  如果想更完美生成随机数,还得做相应的处理!
  4)asort()和 asorti()
  # seq -f "str%.g" 5 |awk '{a[x++]=$0}END{s=asort(a,b);for(i=1;i="[02/Jan/2017:00:02:00" && $4FNR{if($0 in a)print $0}' a b
  3
  4
  5
  # awk 'FNR==NR{a[$0]=1;next}(a[$0]==1)' a b # a[$0]是通过 b 文件每行获取值,如果是 1
  说明有
  # awk 'FNR==NR{a[$0]=1;next}{if(a[$0]==1)print}' a b
  3
  4
  5
  方法 2:
  # awk 'FILENAME=="a"{a[$0]}FILENAME=="b"{if($0 in a)print $0}' a b
  3
  4
  5
  方法 3:
  # awk 'ARGIND==1{a[$0]=1}ARGIND==2 && a[$0]==1' a b
  3
  4
  5
  找出 b 文件在 a 文件不同记录:
  方法 1:
  # awk 'FNR==NR{a[$0];next}!($0 in a)' a b
  6
  7
  # awk 'FNR==NR{a[$0]=1;next}(a[$0]!=1)' a b
  # awk 'FNR==NR{a[$0]=1;next}{if(a[$0]!=1)print}' a b
  6
  7
  方法 2:
  # awk 'FILENAME=="a"{a[$0]=1}FILENAME=="b" && a[$0]!=1' a b
  方法 3:
  # awk 'ARGIND==1{a[$0]=1}ARGIND==2 && a[$0]!=1' a b
  3)合并两个文件
  将 a 文件合并到 b 文件:
  # cat a
  zhangsan 20
  lisi 23
  wangwu 29
  # cat b
  zhangsan man
  lisi woman
  wangwu man
  # awk 'FNR==NR{a[$1]=$0;next}{print a[$1],$2}' a b
  zhangsan 20 man
  lisi 23 woman
  wangwu 29 man
  # awk 'FNR==NR{a[$1]=$0}NR>FNR{print a[$1],$2}' a b
  zhangsan 20 man
  lisi 23 woman
  wangwu 29 man
  将 a 文件相同 IP 的服务名合并:
  # cat a
  192.168.1.1: httpd
  192.168.1.1: tomcat
  192.168.1.2: httpd
  192.168.1.2: postfix
  192.168.1.3: mysqld
  192.168.1.4: httpd
  # awk 'BEGIN{FS=":";OFS=":"}{a[$1]=a[$1] $2}END{for(v in a)print v,a[v]}' a
  192.168.1.4: httpd
  192.168.1.1: httpd tomcat
  192.168.1.2: httpd postfix
  192.168.1.3: mysqld
  说明:数组 a 存储是$1=a[$1] $2,第一个 a[$1]是以第一个字段为下标,值是 a[$1] $2,也就是
  $1=a[$1] $2,值的 a[$1]是用第一个字段为下标获取对应的值,但第一次数组 a 还没有元素,那么
  a[$1]是空值,此时数组存储是 192.168.1.1=httpd,再遇到 192.168.1.1 时,a[$1]通过第一字段
  下标获得上次数组的 httpd,把当前处理的行第二个字段放到上一次同下标的值后面,作为下标
  192.168.1.1 的新值。此时数组存储是 192.168.1.1=httpd tomcat。每次遇到相同的下标(第一个
  字段)就会获取上次这个下标对应的值与当前字段并作为此下标的新值。
  4)将第一列合并到一行
  # cat file
  1 2 3
  4 5 6
  7 8 9
  # awk '{for(i=1;imax)max=$3}END{for(v in a)if(a[v]==max)print v}' a
  g h 3
  e f 3
  7)去除第一行和最后一行
  # seq 5 |awk 'NR>2{print s}{s=$0}'
  2
  3
  4
  读取第一行,NR=1,不执行 print s,s=1
  读取第二行,NR=2,不执行 print s,s=2 (大于为真)
  读取第三行,NR=3,执行 print s,此时 s 是上一次 p 赋值内容 2,s=3
  最后一行,执行 print s,打印倒数第二行,s=最后一行
  获取 Nginx 负载均衡配置端 IP 和端口:
  # cat nginx.conf
  upstream example-servers1 {
  server 127.0.0.1:80 weight=1 max_fails=2 fail_timeout=30s;
  }
  upstream example-servers2 {
  server 127.0.0.1:80 weight=1 max_fails=2 fail_timeout=30s;
  server 127.0.0.1:82 backup;
  }
  # awk '/example-servers1/,/}/{if(NR>2){print s}{s=$2}}' nginx.conf
  127.0.0.1:80
  # awk '/example-servers1/,/}/{if(i>1)print s;s=$2;i++}' nginx.conf
  # awk '/example-servers1/,/}/{if(i>1){print s}{s=$2;i++}}' nginx.conf
  127.0.0.1:80
  读取第一行,i 初始值为 0,0>1 为假,不执行 print s,x=example-servers1,i=1
  读取第二行,i=1,1>1 为假,不执行 print s,s=127.0.0.1:80,i=2
  读取第三行,i=2,2>1 为真,执行 print s,此时 s 是上一次 s 赋值内容 127.0.0.1:80,i=3
  最后一行,执行 print s,打印倒数第二行,s=最后一行。
  这种方式与上面一样,只是用 i++作为计数器。
  8)知道上述方式,就可以实现这种需求了,打印匹配行的上一行
  # seq 5 |awk '/3/{print s}{s=$0}'
  2
  谢谢观看,真心的希望能帮到您!


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-555822-1-1.html 上篇帖子: 第12章代码《跟老男孩学习Linux运维:Shell编程实战》 下篇帖子: linux各种一句话反弹shell总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表