sed流式编辑器

  • sed是一个非交互的文本编辑器,实现的功能跟vim相同,主要是对文件内容进行输出、删除、替换、复制、剪切、导入、导出等功能
  • 命令格式1:前置命令 | sed [选项] ‘[指令]’ 文件名
  • 命令格式2:sed [选项] ‘[指令]’ 文件名
  • 常用选项:
    • -n #屏蔽默认输出,默认sed会将所有的输出结果输出到屏幕中,-n只把sed处理的行输出到屏幕
    • -i #直接修改文件内容,如果不加-i选项,并不会真正改变文件的内容
    • -r #使用扩展正则,若与其他选项连用应作为首个选项
  • 动作指令:
    • p #打印指定的行,如:2,4p 打印第234行,如:2p;4p 打印第2行与第4行
    • d #删除指定的行,如:2,4d 删除第234行
    • s #字符串替换,如:s/旧字串/新字串/
    • r #导入文件内容,如:4r 1.txt 在第4行下导入1.txt文件内容
    • w #导出文件内容,如:3w 1.txt 将文件第三行内容另存到2.txt文件中
  1. #打印文件第一行内容
  2. [root@localhost yunwei]# sed -n '1p' /etc/passwd
  3. root:x:0:0:root:/root:/bin/bash
  4. #打印文件第三行内容
  5. [root@localhost yunwei]# sed -n '3p' /etc/passwd
  6. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  7. #打印文件第3行到6行
  8. [root@localhost yunwei]# sed -n '3,6p' /etc/passwd
  9. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  10. adm:x:3:4:adm:/var/adm:/sbin/nologin
  11. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  12. sync:x:5:0:sync:/sbin:/bin/sync
  13. #打印文件第3行到6行
  14. [root@localhost yunwei]# head -6 /etc/passwd | tail -4
  15. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  16. adm:x:3:4:adm:/var/adm:/sbin/nologin
  17. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  18. sync:x:5:0:sync:/sbin:/bin/sync
  19. #利用正则表达式匹配以root开头的行(正则表达式要放在//内)
  20. [root@localhost yunwei]# sed -n '/^root/p' /etc/passwd
  21. #匹配以bash结尾的行
  22. [root@localhost yunwei]# sed -n '/bash$/p' /etc/passwd
  23. [root@localhost yunwei]# sed -n '/nologin$/p' /etc/passwd
  24. #打印文件最后一行,打印行号
  25. [root@localhost yunwei]# sed -n '$=' /etc/passwd
  26. 70
  27. [root@localhost yunwei]# sed -n '/^root/=' /etc/passwd
  28. 1
  29. #拷贝文件练习
  30. [root@localhost opt]# cp /etc/passwd /opt/test
  31. #删除文件2到4行
  32. [root@localhost opt]# sed '2,4d' test | wc -l
  33. 67
  34. #使用i选项直接修改源文件
  35. [root@localhost opt]# sed -i '2,4d' test
  36. #使用分号分隔
  37. [root@localhost opt]# sed -i '10d;12d' test
  38. [root@localhost opt]# sed -n '$=' test
  39. 62
  40. #制作素材
  41. [root@localhost opt]# vim 1.txt
  42. aaaabbbbb
  43. bbbbbaaaa
  44. cccccaaaaa
  45. dddddaaaa
  46. [root@localhost opt]# sed -n '/aaaa/p' 1.txt
  47. aaaabbbbb
  48. bbbbbaaaa
  49. cccccaaaaa
  50. dddddaaaa
  51. #取反删除
  52. [root@localhost opt]# sed -i '/cccc/!d' 1.txt
  53. [root@localhost opt]# cat 1.txt
  54. ccccaaaa
  55. [root@localhost opt]# vim 1.txt
  56. aaaabbbb
  57. ddddaaaa
  58. zzzzaaaa
  59. ccccaaaa
  60. #删除以ccc开头的行
  61. [root@localhost opt]# sed -i '/^cccc/d' 1.txt
  62. [root@localhost opt]# cat 1.txt
  63. aaaabbbb
  64. ddddaaaa
  65. zzzzaaaa
  66. #删除空行
  67. [root@localhost opt]# sed -i '/^$/d' 1.txt
  68. [root@localhost opt]# cat 1.txt
  69. #准备素材
  70. [root@localhost opt]# vim xx.txt
  71. 2021 2020 2019 2018
  72. 2021 2021 2020 2019
  73. 2021 2022 2021 2020
  74. #替换文件每一行匹配到的第一个字串
  75. [root@localhost opt]# sed 's/2021/xxxx/' xx.txt
  76. xxxx 2020 2019 2018
  77. xxxx 2021 2020 2019
  78. xxxx 2022 2021 2020
  79. #替换文件每一行匹配到的第二个字串
  80. [root@localhost opt]# sed 's/2021/xxxx/2' xx.txt
  81. 2021 2020 2019 2018
  82. 2021 xxxx 2020 2019
  83. 2021 2022 xxxx 2020
  84. #替换文件每一行匹配到的所有指定字串
  85. [root@localhost opt]# sed 's/2021/xxxx/g' xx.txt
  86. xxxx 2020 2019 2018
  87. xxxx xxxx 2020 2019
  88. xxxx 2022 xxxx 2020
  89. #将匹配到的第一个字串替换成空
  90. [root@localhost opt]# sed 's/2021//' xx.txt
  91. 2020 2019 2018
  92. 2021 2020 2019
  93. 2022 2021 2020
  94. #将匹配到的第=二字串替换成空
  95. [root@localhost opt]# sed 's/2021//2' xx.txt
  96. 2021 2020 2019 2018
  97. 2021 2020 2019
  98. 2021 2022 2020
  99. #替换时屏蔽默认输出
  100. [root@localhost opt]# sed -n 's/root/xxoo/g' test
  101. [root@localhost opt]# sed -n 's/root/xxoo/gp' test
  102. xxoo:x:0:0:xxoo:/xxoo:/bin/bash
  103. operator:x:11:0:operator:/xxoo:/sbin/nologin
  104. #替换符可以使用任意的特殊符号
  105. [root@localhost opt]# sed 's#2021#xxoo#' xx.txt
  106. xxoo 2020 2019 2018
  107. xxoo 2021 2020 2019
  108. xxoo 2022 2021 2020
  109. [root@localhost opt]# sed 's,2021,xxoo,' xx.txt
  110. xxoo 2020 2019 2018
  111. xxoo 2021 2020 2019
  112. xxoo 2022 2021 2020
  113. [root@localhost opt]# sed 's!2021!xxoo!' xx.txt
  114. xxoo 2020 2019 2018
  115. xxoo 2021 2020 2019
  116. xxoo 2022 2021 2020
  117. [root@localhost opt]# sed 's;2021;xxoo;' xx.txt
  118. xxoo 2020 2019 2018
  119. xxoo 2021 2020 2019
  120. xxoo 2022 2021 2020
  121. [root@localhost opt]# sed 's*2021*xxoo*' xx.txt
  122. xxoo 2020 2019 2018
  123. xxoo 2021 2020 2019
  124. xxoo 2022 2021 2020
  125. [root@localhost opt]# sed 's:2021:xxoo:' xx.txt
  126. xxoo 2020 2019 2018
  127. xxoo 2021 2020 2019
  128. xxoo 2022 2021 2020
  129. #将文件中/bin/bash替换成/bin/sh
  130. [root@localhost opt]# sed -n 's/\/bin\/bash/\/bin\/sh/gp' test
  131. [root@localhost opt]# sed -n 's,/bin/bash,/bin/sh,gp' test
  132. #使用sed给文件1-7行批量添加注释
  133. [root@localhost opt]# sed -n '1,7s/^/#/p' test
  134. #使用sed给文件1-7行批量添加注释,直接修改源文件
  135. [root@localhost opt]# sed -i '1,7s/^/#/p' test
  136. #批量去除1-7行的注释
  137. [root@localhost opt]# sed -n '1,7s/^#//p' test
  138. #批量去除1-7行的注释,直接修改源文件
  139. [root@localhost opt]# sed -i '1,7s/^#//p' test
  140. #将文件中所有的数字替换成空
  141. [root@localhost opt]# sed -n 's/[0-9]//gp' test
  142. #将文件中所有的英文字母替换成空
  143. [root@localhost opt]# sed -n 's/[a-Z]//gp' test
  144. #准备素材
  145. [root@localhost opt]# vim a.txt
  146. xxxxxxx
  147. yyyyyyy
  148. zzzzzz
  149. #将a.txt文件内容导入到test文件中,默认读一行导一遍
  150. [root@localhost opt]# sed 'r/opt/a.txt' test
  151. #指定导入的行,导入到test文件第一行下边
  152. [root@localhost opt]# sed '1r/opt/a.txt' test
  153. root:x:0:0:root:/root:/bin/bash
  154. xxxxxxx
  155. yyyyyyy
  156. zzzzzz
  157. #指定连续导入的行
  158. [root@localhost opt]# sed '1,3r/opt/a.txt' test
  159. root:x:0:0:root:/root:/bin/bash
  160. xxxxxxx
  161. yyyyyyy
  162. zzzzzz
  163. root:x:0:0:root:/root:/bin/bash
  164. xxxxxxx
  165. yyyyyyy
  166. zzzzzz
  167. root:x:0:0:root:/root:/bin/bash
  168. xxxxxxx
  169. yyyyyyy
  170. zzzzzz
  171. #将a.txt文件第一行内容导出到b.txt文件中
  172. [root@localhost opt]# sed '1w b.txt' a.txt
  173. [root@localhost opt]# cat b.txt
  174. xxxxxxx

awk编程语言

  • awk编程语言/数据处理引擎
  • 创造者:Aho Winberger Kernighan
  • 基于模式匹配检查输入文本,逐行处理并输出,获取指定的数据
  • awk过滤数据时支持仅打印某一列,如:第2列、第4列…
  • awk命令格式1:awk [选项] ‘条件1{指令} 条件2{指令}’ 文件名
  • awk命令格式2:前置命令 | awk [选项] ‘条件{指令}’
  • 常用指令:print 是最常用的打印指令
  • 常用选项:-F #指定分隔符,如不指定分隔符,默认以空格或tab键为默认分隔符,可通过[]集合匹配多种单个字符
  • awk内置变量:$1第一列,$2第二列,$3第三列,依次类推,NR文件当前行号,NF文件当前列数
  • 命令格式1示例:
  1. #准备素材
  2. [root@localhost opt]# vim test.txt
  3. hello the woman
  4. welcome to china
  5. #打印文件的第一列
  6. [root@localhost opt]# awk '{print $1}' test.txt
  7. hello
  8. welcome
  9. #打印文件第一列和第三列
  10. [root@localhost opt]# awk '{print $1,$3}' test.txt
  11. hello woman
  12. welcome china
  13. #打印passwd文件第一列(默认没有空格与tab键作为分隔符,打印文件所有内容)
  14. [root@localhost opt]# awk '{print $1}' /etc/passwd
  15. #手动指定以:作为分隔,打印文件第一列
  16. [root@localhost opt]# awk -F: '{print $1}' /etc/passwd
  17. #打印文件第一列与第七列
  18. [root@localhost opt]# awk -F: '{print $1,$7}' /etc/passwd
  19. #通过[]集合匹配多种单个字符作为分隔符,打印用户名与解释器字段
  20. [root@localhost opt]# awk -F[:/] '{print $1,$10}' /etc/passwd
  21. #通过正则表达式过滤以root开头的行
  22. [root@localhost opt]# awk -F: '/^root/{print}' /etc/passwd
  23. root:x:0:0:root:/root:/bin/bash
  24. #通过正则表达式过滤以root开头的行,打印第1列与第7列
  25. [root@localhost opt]# awk -F: '/^root/ {print $1,$7}' /etc/passwd
  26. root /bin/bash
  27. #打印文件每一行与每一行的列数
  28. [root@localhost opt]# awk -F: '{print NR,NF}' /etc/passwd
  29. #打印文件每一行与每一行的列数,并打印最后一列
  30. [root@localhost opt]# awk -F: '{print NR,NF,$NF}' /etc/passwd
  31. #通过常量打印执行的列
  32. [root@localhost opt]# awk -F: '{print $1,"用户的解释器为:",$7}' /etc/passwd
  33. root 用户的解释器为: /bin/bash
  34. #匹配第一列包含root的行
  35. [root@localhost opt]# awk -F: '$1~/root/' /etc/passwd
  36. root:x:0:0:root:/root:/bin/bash
  37. #排除第7列noloogin的行,打印第1列与第7列
  38. [root@localhost opt]# awk -F: '$7!~/nologin/{print $1,$7}' /etc/passwd
  39. #利用扩展正则过滤,以root或者adm开头的行,打印第1列与第7列
  40. [root@localhost opt]# awk -F: '/^(root|adm)/{print $1,$7}' /etc/passwd
  41. root /bin/bash
  42. adm /sbin/nologin

awk使用数值/字符串比较设置条件

  • 等于: ==
  • 不等于: !=
  • 大于: >
  • 大于等于: >=
  • 小于: <
  • 小于等于:<=
  1. #打印行号等于3
  2. [root@localhost opt]# awk 'NR==3{print}' /etc/passwd
  3. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  4. #使用sed更加方便打印某一行
  5. [root@localhost opt]# sed -n '3p' /etc/passwd
  6. daemon:x:2:2:daemon:/sbin:/sbin/nologin
  7. #打印文件中第3列大于等于1000,打印第1列,第3列,第7列
  8. [root@localhost opt]# awk -F: '$3>=1000{print $1,$3,$7}' /etc/passwd
  9. lisi 1000 /bin/bash
  10. #打印文件中第三列小于1000,打印第1列,第3列,第7列
  11. [root@localhost opt]# awk -F: '$3<1000{print $1,$3,$7}' /etc/passwd
  12. root 0 /bin/bash
  13. #打印文件中第3列大于500并且小于1000,打印第1列,第3列,第7列
  14. [root@localhost opt]# awk -F: '$3>500 && $3<1000 {print $1,$3,$7}' /etc/passwd
  15. polkitd 999 /sbin/nologin
  16. #打印第一列不等于root的行
  17. [root@localhost opt]# awk -F: '$1!="root"{print}' /etc/passwd

awk过滤时机:awk ‘BEGIN{指令} {指令} END{指令}’ 文件名

  • BEGIN{指令} #读取文件内容之前执行指令,指令执行一次,行前处理
  • {指令} #读取文件过程中执行,指令逐行执行,读一行,执行一次
  • END{指令} #读取文件内容结束后执行指令,指令执行一次,行后处理
  1. #BEGIN{指令}行前处理
  2. [root@localhost opt]# awk 'BEGIN{print "正在处理中"}'
  3. 正在处理中
  4. #定义变量
  5. [root@localhost opt]# awk "BEGIN{x=10;print x}"
  6. 10
  7. #四则运算
  8. [root@localhost opt]# awk "BEGIN{x=10;print x+5}"
  9. 15
  10. [root@localhost opt]# awk "BEGIN{x=10;print x+5}"
  11. 15
  12. [root@localhost opt]# awk "BEGIN{x=10;print x-5}"
  13. 5
  14. [root@localhost opt]# awk "BEGIN{x=10;print x*5}"
  15. 50
  16. [root@localhost opt]# awk "BEGIN{x=10;print x/5}"
  17. 2
  18. [root@localhost opt]# awk "BEGIN{print 10+10}"
  19. 20
  20. [root@localhost opt]# awk "BEGIN{print 10-5}"
  21. 5
  22. [root@localhost opt]# awk "BEGIN{print 10*2}"
  23. 20
  24. [root@localhost opt]# awk "BEGIN{print 10/3}"
  25. 3.33333
  26. [root@localhost opt]# awk "BEGIN{print 10%3}"
  27. 1
  28. #通过awk统计系统里使用bash解释器的用户有什么个?
  29. [root@localhost opt]# awk 'BEGIN{x=0}/bash$/{x++}END{print x}' /etc/passwd
  30. 27
  31. [root@localhost opt]# awk '/bash$/{x++}END{print x}' /etc/passwd
  32. 27

awk分支结构

  • if单分支格式:if(条件){指令}
  • if双分支格式:if(条件){指令}else{指令}
  1. #if单分支统计passwd文件中UID大于或等于1000的用户个数
  2. awk -F: '{if($3>=1000){x++}} END{print x}' /etc/passwd
  3. if($3>=1000){x++}
  4. [root@localhost ~]# awk -F: '{if($3>=1000){x++}}END{print x}' /etc/passwd
  5. #if双分支统计passwd文件中UID大于等于1000的用户,和小于1000的用户个数
  6. [root@localhost ~]# awk -F: '{if($3>=1000){i++} else{x++}} END{print i,x}' /etc/passwd

awk数组

  • 定义数组格式1:数组名[下标]=值
  • 定义数组格式2:数组名[下标]
  • 数组的用法:for(变量名 in 数组名) {print 数组名[变量]}
#awk定义数组方式
[root@localhost ~]# awk 'BEGIN{x[0]=10;x[1]=20;print x[0],x[1]}'
10 20

#awk定义数组方式
[root@localhost ~]# awk 'BEGIN{x[0]++;print x[0]}'
1

awk循环结构

  • 命令格式:for(变量名 in 数组名){print 数组名[变量]}
[root@localhost ~]# awk 'BEGIN{a[0]=00;a[1]=11;a[2]=22;for(i in a){print i,a[i]}}'
0 0
1 11
2 22
  • awk命令格式2:前置命令 | awk [选项] ‘条件{指令}’
#通过awk打印剩余内存
[root@localhost opt]# free -h | grep Mem | awk '{print $4}'
134M
[root@localhost opt]# free -h | awk '/Mem/{print $4}'
134M

#用awk写一个监控脚本,监控网卡的进出口流量
[root@localhost ~]# vim while_liuliang.sh 
#!/bin/bash
while :
do
        clear
        ifconfig ens32 | awk '/inet /{print "IP:",$2}'
        ifconfig ens32 | awk '/RX p/{print "入口流量:",$5}'
        ifconfig ens32 | awk '/TX p/{print "出口流量:",$5}'
        sleep 0.1
done

#使用awk过滤系统根分区使用情况
[root@localhost ~]# df -h | grep '/$' | awk '{print $4}' | awk -FG '{print $1}'
51

#过滤根分区剩余空间与物理内存空间
[root@localhost ~]# vim df_free.sh
#!/bin/bash
df -h | grep '/$' | awk '{print "根分区剩余空间:",$4}'
free -h | grep Mem | awk '{print "物理内存剩余空间:", $4}'

#通过awk统计用户登录系统的次数
[root@localhost ~]# who | awk '{ip[$1]++}END{for(i in ip)print i,ip[i]}'
root 1