Linux-笔记11
#### 字符串截取
- 在使用shell脚本完成各种运维任务时,一旦涉及到判断、条件测试等相关操作时往往需要对相关的命令输出进行过滤,提取出符合要求的字符串
- 字符串截取的常用方法:${变量名:起始位置:长度}
- ${}截取字符串时,起始位置是从0开始的
```shell
[root@localhost yunwei]# phone=13812345678
[root@localhost yunwei]# echo $phone
13812345678
#统计变量的个数
[root@localhost yunwei]# echo ${#phone}
11
#截取变量的前三位,在截取时包含数字本身
[root@localhost yunwei]# echo ${phone:0:3}
138
#截取后四位
[root@localhost yunwei]# echo ${phone:7:4}
5678
#截取中间四位
[root@localhost yunwei]# echo ${phone:3:4}
1234
#截取一个随机的8位密码
[root@localhost yunwei]# vim mima.sh
#!/bin/bash
x=qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789
for i in {1..8}
do
n=$[RANDOM%62]
p=${x:n:1}
pass=$pass$p
done
echo $pass
[root@localhost yunwei]# ./mima.sh
42iVW9Ba
[root@localhost yunwei]# ./mima.sh
XuEcVGoR
```
#### 字符串替换
- 只替换第一个匹配的结果:${变量名/xx/yy}
- 替换全部匹配的结果:${变量名//xx/yy}
```shell
#只替换匹配到的第一个字符
[root@localhost yunwei]# echo $phone
13812345678
#将匹配到的第一个3替换成4
[root@localhost yunwei]# echo ${phone/3/4}
14812345678
#将匹配到的所有3替换成4
[root@localhost yunwei]# echo ${phone//3/4}
14812445678
```
#### 字符串掐头去尾
- 从左向右,最短匹配删除:${变量名#*关键词}
- 从左向右,最长匹配删除:${变量名##*关键词}
- 从右向左,最短匹配删除:${变量名%关键词*}
- 从右向左,最长匹配删除:${变量名%%关键词*}
```shell
#定义素材
[root@localhost yunwei]# x=`head -1 /etc/passwd`
[root@localhost yunwei]# echo $x
root:x:0:0:root:/root:/bin/bash
#从左到右最短匹配
[root@localhost yunwei]# echo ${x#root}
:x:0:0:root:/root:/bin/bash
#从左到右最短匹配,不加*只匹配最左侧的字串
[root@localhost yunwei]# echo ${x#0}
root:x:0:0:root:/root:/bin/bash
#从左到右最短匹配,加*匹配遇到的第一个字串
[root@localhost yunwei]# echo ${x#*0}
:0:root:/root:/bin/bash
#从左到右最长匹配
[root@localhost yunwei]# echo ${x##0}
root:x:0:0:root:/root:/bin/bash
#从左到右最长匹配
[root@localhost yunwei]# echo ${x##*0}
:root:/root:/bin/bash
#从右到做最短匹配
[root@localhost yunwei]# echo ${x%/bash}
root:x:0:0:root:/root:/bin
#从右到做最短匹配
[root@localhost yunwei]# echo ${x%root*}
root:x:0:0:root:/
#从右向左最长匹配
[root@localhost yunwei]# echo ${x%%root*}
#从右向左最短匹配
[root@localhost yunwei]# echo ${x%0*}
root:x:0:
#从右向左最长匹配
[root@localhost yunwei]# echo ${x%%0*}
root:x:
#把文件以.doc结尾的扩展名,全部改为.txt
[root@localhost yunwei]# touch {1..100}.doc
[root@localhost yunwei]# ls
100.doc 17.doc 24.doc 31.doc 39.doc 46.doc 53.doc 60.doc 68.doc 75.doc 82.doc 8.doc 97.doc if2.sh while.sh
10.doc 18.doc 25.doc 32.doc 3.doc 47.doc 54.doc 61.doc 69.doc 76.doc 83.doc 90.doc 98.doc if3.sh
11.doc 19.doc 26.doc 33.doc 40.doc 48.doc 55.doc 62.doc 6.doc 77.doc 84.doc 91.doc 99.doc if4.sh
12.doc 1.doc 27.doc 34.doc 41.doc 49.doc 56.doc 63.doc 70.doc 78.doc 85.doc 92.doc 9.doc if5.sh
13.doc 20.doc 28.doc 35.doc 42.doc 4.doc 57.doc 64.doc 71.doc 79.doc 86.doc 93.doc case.sh mima.sh
14.doc 21.doc 29.doc 36.doc 43.doc 50.doc 58.doc 65.doc 72.doc 7.doc 87.doc 94.doc for1.sh ping.sh
15.doc 22.doc 2.doc 37.doc 44.doc 51.doc 59.doc 66.doc 73.doc 80.doc 88.doc 95.doc fork.sh user.sh
16.doc 23.doc 30.doc 38.doc 45.doc 52.doc 5.doc 67.doc 74.doc 81.doc 89.doc 96.doc if1.sh while1.sh
#字符串去尾方式批量修改文件扩展名
[root@localhost yunwei]# vim file.sh
#!/bin/bash
for i in `ls *.doc`
do
mv $i ${i%doc}txt
done
#字符串替换方式批修改文件扩展名
[root@localhost yunwei]# vim file.sh
#!/bin/bash
for i in `ls *.txt`
do
mv $i ${i/txt/doc}
done
```
#### shell数组
```shell
#定义数组方式一:数组名=(值1 值2 值3 .. .. 值n)
[root@localhost yunwei]# x=(11 22 33 44 55 abc)
[root@localhost yunwei]# echo $x
11
#按照下标取值,下标从0起使,0就是数据内的第一个值
[root@localhost yunwei]# echo ${x[0]}
11
[root@localhost yunwei]# echo ${x[0]}
11
[root@localhost yunwei]# echo ${x[1]}
22
[root@localhost yunwei]# echo ${x[2]}
33
[root@localhost yunwei]# echo ${x[3]}
44
[root@localhost yunwei]# echo ${x[4]}
55
#获取数组内所有值
[root@localhost yunwei]# echo ${x[@]}
11 22 33 44 55 abc
#定义数组方式二:数组名[下标]=值
[root@localhost yunwei]# b[0]=aa
[root@localhost yunwei]# b[1]=xx
[root@localhost yunwei]# b[2]=xxoo
[root@localhost yunwei]# echo ${b[0]}
aa
[root@localhost yunwei]# echo ${b[1]}
xx
[root@localhost yunwei]# echo ${b[2]}
xxoo
[root@localhost yunwei]# echo ${b[@]}
aa xx xxoo
[root@localhost yunwei]# echo ${b[*]}
aa xx xxoo
```
#### 正则表达式
- 正则表达式使用一串符号描述有共同属性的数据
| 基本正则符号 | 描述 |
| ------- | ------------------------- |
| ^ | 匹配行首 |
| $ | 匹配行尾 |
| [] | 集合,匹配集合中的任意单个字符 |
| [^] | 对集合取反 |
| . | 匹配任意单个字符 |
| * | 匹配前一个字符出现的任意次数[*不允许单独[使用] |
| \{n,m\} | 匹配前一个字符 n 到 m 次 |
| \{n\} | 匹配前一个字符 n 次 |
```shell
#匹配以什么什么开头的行
[root@localhost yunwei]# grep "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost yunwei]# grep "^#" /etc/fstab
#匹配以什么什么结尾的行
[root@localhost yunwei]# grep "bash$" /etc/passwd
[root@localhost yunwei]# grep -v "^#" /etc/fstab
[root@localhost yunwei]# grep -v "^#" /etc/fstab | grep -v "^$"
#集合,匹配集合中的任意单个字符
[root@localhost yunwei]# grep "ro[abcotabcd]" /etc/passwd
#集合,对集合中的任意单个字符取反
[root@localhost yunwei]# grep "ro[^abcotabcd]" /etc/passwd
#匹配任意单个字符
[root@localhost yunwei]# grep "roo." /etc/passwd
[root@localhost yunwei]# grep ".oot" /etc/passwd
[root@localhost yunwei]# grep "w.*" /etc/passwd
#准备素材
[root@localhost yunwei]# vim 1.txt
a
b
ab
aab
acb
adb
amnb
amnbmnbmnb
aaaabaaaaaaabaaaaaaaaaaaaab
aabb the ccdd
abcthe
thexxoo
xxootheooxx
[root@localhost yunwei]# grep "a*b" 1.txt
[root@localhost yunwei]# grep "a.*b" 1.txt
[root@localhost yunwei]# grep ".*b" 1.txt
[root@localhost yunwei]# grep "a.*" 1.txt
#匹配前一个字符至少出现一次以上,\{n,m\}
[root@localhost yunwei]# grep "a\{1,\}" 1.txt
#匹配前一个字符 n 次,\{n\}
[root@localhost yunwei]# grep "o\{2\}" /etc/passwd
[root@localhost yunwei]# grep "a\{2\}" 1.txt
```
| **扩展正则符号** | **描述** |
| ---------- | ------------ |
| + | 最少匹配一次 |
| ? | 最多匹配一次 |
| {n,m} | 匹配 n 到 m 次 |
| () | 组合为整体,保留(复制) |
| \| | 或者 |
| \b | 单词边界 |
```shell
#基本正则用法
[root@localhost yunwei]# grep "a\{2,4\}b" 1.txt
#使用扩展正则时,需要使用egrep命令过滤
[root@localhost yunwei]# egrep "a{2,4}b" 1.txt
#匹配前一个字符至少出现一次以上
[root@localhost yunwei]# egrep "a+" 1.txt
#基本正则实现方式,匹配前一个字符至少出现一次以上
[root@localhost yunwei]# grep "a\{1,\}" 1.txt
#匹配前一个字符出现了0次或一次
[root@localhost yunwei]# egrep "a?b" 1.txt
#基本正则实现方式,匹配前一个字符出现了0次或一次
[root@localhost yunwei]# grep "a\{0,1\}b" 1.txt
#或者
[root@localhost yunwei]# egrep "ab|acb|aaab" 1.txt
#组合为整体
[root@localhost yunwei]# egrep "(ab)" 1.txt
ab
aab
aaaabaaaaaaabaaaaaaaaaaaaab
[root@localhost yunwei]# egrep "(acb)" 1.txt
acb
[root@localhost yunwei]# egrep "(aaab)" 1.txt
#单词边界
[root@localhost yunwei]# grep "the" 1.txt
aabb the ccdd
abcthe
thexxoo
xxootheooxx
[root@localhost yunwei]# egrep "\bthe\b" 1.txt
aabb the ccdd
[root@localhost yunwei]# egrep "\bthe" 1.txt
aabb the ccdd
thexxoo
[root@localhost yunwei]# egrep "the\b" 1.txt
aabb the ccdd
abcthe
```
#### 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文件中
```shell
#打印文件第一行内容
[root@localhost yunwei]# sed -n '1p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
#打印文件第三行内容
[root@localhost yunwei]# sed -n '3p' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
#打印文件第3行到6行
[root@localhost yunwei]# sed -n '3,6p' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
#打印文件第3行到6行
[root@localhost yunwei]# head -6 /etc/passwd | tail -4
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
#利用正则表达式匹配以root开头的行(正则表达式要放在//内)
[root@localhost yunwei]# sed -n '/^root/p' /etc/passwd
#匹配以bash结尾的行
[root@localhost yunwei]# sed -n '/bash$/p' /etc/passwd
[root@localhost yunwei]# sed -n '/nologin$/p' /etc/passwd
#打印文件最后一行,打印行号
[root@localhost yunwei]# sed -n '$=' /etc/passwd
70
[root@localhost yunwei]# sed -n '/^root/=' /etc/passwd
1
#拷贝文件练习
[root@localhost opt]# cp /etc/passwd /opt/test
#删除文件2到4行
[root@localhost opt]# sed '2,4d' test | wc -l
67
#使用i选项直接修改源文件
[root@localhost opt]# sed -i '2,4d' test
#使用分号分隔
[root@localhost opt]# sed -i '10d;12d' test
[root@localhost opt]# sed -n '$=' test
62
#制作素材
[root@localhost opt]# vim 1.txt
aaaabbbbb
bbbbbaaaa
cccccaaaaa
dddddaaaa
[root@localhost opt]# sed -n '/aaaa/p' 1.txt
aaaabbbbb
bbbbbaaaa
cccccaaaaa
dddddaaaa
#取反删除
[root@localhost opt]# sed -i '/cccc/!d' 1.txt
[root@localhost opt]# cat 1.txt
ccccaaaa
[root@localhost opt]# vim 1.txt
aaaabbbb
ddddaaaa
zzzzaaaa
ccccaaaa
#删除以ccc开头的行
[root@localhost opt]# sed -i '/^cccc/d' 1.txt
[root@localhost opt]# cat 1.txt
aaaabbbb
ddddaaaa
zzzzaaaa
#删除空行
[root@localhost opt]# sed -i '/^$/d' 1.txt
[root@localhost opt]# cat 1.txt
#准备素材
[root@localhost opt]# vim xx.txt
2021 2020 2019 2018
2021 2021 2020 2019
2021 2022 2021 2020
#替换文件每一行匹配到的第一个字串
[root@localhost opt]# sed 's/2021/xxxx/' xx.txt
xxxx 2020 2019 2018
xxxx 2021 2020 2019
xxxx 2022 2021 2020
#替换文件每一行匹配到的第二个字串
[root@localhost opt]# sed 's/2021/xxxx/2' xx.txt
2021 2020 2019 2018
2021 xxxx 2020 2019
2021 2022 xxxx 2020
#替换文件每一行匹配到的所有指定字串
[root@localhost opt]# sed 's/2021/xxxx/g' xx.txt
xxxx 2020 2019 2018
xxxx xxxx 2020 2019
xxxx 2022 xxxx 2020
#将匹配到的第一个字串替换成空
[root@localhost opt]# sed 's/2021//' xx.txt
2020 2019 2018
2021 2020 2019
2022 2021 2020
#将匹配到的第=二字串替换成空
[root@localhost opt]# sed 's/2021//2' xx.txt
2021 2020 2019 2018
2021 2020 2019
2021 2022 2020
#替换时屏蔽默认输出
[root@localhost opt]# sed -n 's/root/xxoo/g' test
[root@localhost opt]# sed -n 's/root/xxoo/gp' test
xxoo:x:0:0:xxoo:/xxoo:/bin/bash
operator:x:11:0:operator:/xxoo:/sbin/nologin
#替换符可以使用任意的特殊符号
[root@localhost opt]# sed 's#2021#xxoo#' xx.txt
xxoo 2020 2019 2018
xxoo 2021 2020 2019
xxoo 2022 2021 2020
[root@localhost opt]# sed 's,2021,xxoo,' xx.txt
xxoo 2020 2019 2018
xxoo 2021 2020 2019
xxoo 2022 2021 2020
[root@localhost opt]# sed 's!2021!xxoo!' xx.txt
xxoo 2020 2019 2018
xxoo 2021 2020 2019
xxoo 2022 2021 2020
[root@localhost opt]# sed 's;2021;xxoo;' xx.txt
xxoo 2020 2019 2018
xxoo 2021 2020 2019
xxoo 2022 2021 2020
[root@localhost opt]# sed 's*2021*xxoo*' xx.txt
xxoo 2020 2019 2018
xxoo 2021 2020 2019
xxoo 2022 2021 2020
[root@localhost opt]# sed 's:2021:xxoo:' xx.txt
xxoo 2020 2019 2018
xxoo 2021 2020 2019
xxoo 2022 2021 2020
#将文件中/bin/bash替换成/bin/sh
[root@localhost opt]# sed -n 's/\/bin\/bash/\/bin\/sh/gp' test
[root@localhost opt]# sed -n 's,/bin/bash,/bin/sh,gp' test
#使用sed给文件1-7行批量添加注释
[root@localhost opt]# sed -n '1,7s/^/#/p' test
#使用sed给文件1-7行批量添加注释,直接修改源文件
[root@localhost opt]# sed -i '1,7s/^/#/' test
#批量去除1-7行的注释
[root@localhost opt]# sed -n '1,7s/^#//' test
#批量去除1-7行的注释,直接修改源文件
[root@localhost opt]# sed -i '1,7s/^#//' test
#将文件中所有的数字替换成空
[root@localhost opt]# sed -n 's/[0-9]//gp' test
#将文件中所有的英文字母替换成空
[root@localhost opt]# sed -n 's/[a-Z]//gp' test
#准备素材
[root@localhost opt]# vim a.txt
xxxxxxx
yyyyyyy
zzzzzz
#将a.txt文件内容导入到test文件中,默认读一行导一遍
[root@localhost opt]# sed 'r/opt/a.txt' test
#指定导入的行,导入到test文件第一行下边
[root@localhost opt]# sed '1r/opt/a.txt' test
root:x:0:0:root:/root:/bin/bash
xxxxxxx
yyyyyyy
zzzzzz
#指定连续导入的行
[root@localhost opt]# sed '1,3r/opt/a.txt' test
root:x:0:0:root:/root:/bin/bash
xxxxxxx
yyyyyyy
zzzzzz
root:x:0:0:root:/root:/bin/bash
xxxxxxx
yyyyyyy
zzzzzz
root:x:0:0:root:/root:/bin/bash
xxxxxxx
yyyyyyy
zzzzzz
#将a.txt文件第一行内容导出到b.txt文件中
[root@localhost opt]# sed '1w b.txt' a.txt
[root@localhost opt]# cat b.txt
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示例:
```shell
#准备素材
[root@localhost opt]# vim test.txt
hello the woman
welcome to china
#打印文件的第一列
[root@localhost opt]# awk '{print $1}' test.txt
hello
welcome
#打印文件第一列和第三列
[root@localhost opt]# awk '{print $1,$3}' test.txt
hello woman
welcome china
#打印passwd文件第一列(默认没有空格与tab键作为分隔符,打印文件所有内容)
[root@localhost opt]# awk '{print $1}' /etc/passwd
#手动指定以:作为分隔,打印文件第一列
[root@localhost opt]# awk -F: '{print $1}' /etc/passwd
#打印文件第一列与第七列
[root@localhost opt]# awk -F: '{print $1,$7}' /etc/passwd
#通过[]集合匹配多种单个字符作为分隔符,打印用户名与解释器字段
[root@localhost opt]# awk -F[:/] '{print $1,$10}' /etc/passwd
#通过正则表达式过滤以root开头的行
[root@localhost opt]# awk -F: '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
#通过正则表达式过滤以root开头的行,打印第1列与第7列
[root@localhost opt]# awk -F: '/^root/ {print $1,$7}' /etc/passwd
root /bin/bash
#打印文件每一行与每一行的列数
[root@localhost opt]# awk -F: '{print NR,NF}' /etc/passwd
#打印文件每一行与每一行的列数,并打印最后一列
[root@localhost opt]# awk -F: '{print NR,NF,$NF}' /etc/passwd
#通过常量打印执行的列
[root@localhost opt]# awk -F: '{print $1,"用户的解释器为:",$7}' /etc/passwd
root 用户的解释器为: /bin/bash
#匹配第一列包含root的行
[root@localhost opt]# awk -F: '$1~/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
#排除第7列noloogin的行,打印第1列与第7列
[root@localhost opt]# awk -F: '$7!~/nologin/{print $1,$7}' /etc/passwd
#利用扩展正则过滤,以root或者adm开头的行,打印第1列与第7列
[root@localhost opt]# awk -F: '/^(root|adm)/{print $1,$7}' /etc/passwd
root /bin/bash
adm /sbin/nologin
```
- awk使用数值/字符串比较设置条件
- 等于: ==
- 不等于: !=
- 大于: >
- 大于等于: >=
- 小于: <
- 小于等于:<=
```shell
#打印行号等于3
[root@localhost opt]# awk 'NR==3{print}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
#使用sed更加方便打印某一行
[root@localhost opt]# sed -n '3p' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
#打印文件中第3列大于等于1000,打印第1列,第3列,第7列
[root@localhost opt]# awk -F: '$3>=1000{print $1,$3,$7}' /etc/passwd
lisi 1000 /bin/bash
#打印文件中第三列小于1000,打印第1列,第3列,第7列
[root@localhost opt]# awk -F: '$3<1000{print $1,$3,$7}' /etc/passwd
root 0 /bin/bash
#打印文件中第3列大于500并且小于1000,打印第1列,第3列,第7列
[root@localhost opt]# awk -F: '$3>500 && $3<1000 {print $1,$3,$7}' /etc/passwd
polkitd 999 /sbin/nologin
#打印第一列不等于root的行
[root@localhost opt]# awk -F: '$1!="root"{print}' /etc/passwd
```
- awk过滤时机:awk ‘BEGIN{指令} {指令} END{指令}’ 文件名
- BEGIN{指令} #读取文件内容之前执行指令,指令执行一次,行前处理
- {指令} #读取文件过程中执行,指令逐行执行,读一行,执行一次
- END{指令} #读取文件内容结束后执行指令,指令执行一次,行后处理
```shell
#BEGIN{指令}行前处理
[root@localhost opt]# awk 'BEGIN{print "正在处理中"}'
正在处理中
#定义变量
[root@localhost opt]# awk "BEGIN{x=10;print x}"
10
#四则运算
[root@localhost opt]# awk "BEGIN{x=10;print x+5}"
15
[root@localhost opt]# awk "BEGIN{x=10;print x+5}"
15
[root@localhost opt]# awk "BEGIN{x=10;print x-5}"
5
[root@localhost opt]# awk "BEGIN{x=10;print x*5}"
50
[root@localhost opt]# awk "BEGIN{x=10;print x/5}"
2
[root@localhost opt]# awk "BEGIN{print 10+10}"
20
[root@localhost opt]# awk "BEGIN{print 10-5}"
5
[root@localhost opt]# awk "BEGIN{print 10*2}"
20
[root@localhost opt]# awk "BEGIN{print 10/3}"
3.33333
[root@localhost opt]# awk "BEGIN{print 10%3}"
1
#通过awk统计系统里使用bash解释器的用户有什么个?
[root@localhost opt]# awk 'BEGIN{x=0}/bash$/{x++}END{print x}' /etc/passwd
27
[root@localhost opt]# awk '/bash$/{x++}END{print x}' /etc/passwd
27
```
- awk分支结构
- if单分支格式:if(条件){指令}
- if双分支格式:if(条件){指令}else{指令}
```shell
#if单分支统计passwd文件中UID大于或等于1000的用户个数
awk -F: '{if($3>=1000){x++}} END{print x}' /etc/passwd
if($3>=1000){x++}
[root@localhost ~]# awk -F: '{if($3>=1000){x++}}END{print x}' /etc/passwd
#if双分支统计passwd文件中UID大于等于1000的用户,和小于1000的用户个数
[root@localhost ~]# awk -F: '{if($3>=1000){i++} else{x++}} END{print i,x}' /etc/passwd
```
- awk数组
- 定义数组格式1:数组名[下标]=值
- 定义数组格式2:数组名[下标]
- 数组的用法:for(变量名 in 数组名) {print 数组名[变量]}
```shell
#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 数组名[变量]}
```shell
[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 [选项] '条件{指令}'
```shell
#通过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
```

浙公网安备 33010602011771号