Shell awk文本处理,shell脚本编写
一:内容包含awk、变量、运算符、if多分支
<a>语法糖:
awk [options] 'commands' files
option
-F 定义字段分隔符,默认的分隔符是连续的空格或制表符
使用option中的-F参数定义间隔符号
用$1,$2,$3等的顺序表示files中每行以间隔符号分隔的各列不同域
NF变量表示当前记录的字段数
-v 定义变量并赋值 也可以借用次方式从shell变量中引入
command
<b>读前处理 行处理 读后处理:
1.读前处理 BEGIN{awk_cmd1;awk_cmd2}
2.行处理:定址 命令
定址方法: 正则,变量,比较和关系运算
<c>正则需要用//包围起来
^ 行首
$ 行尾
. 除了换行符以外的任意单个字符
* 前导字符的零个或多个
.* 所有字符
[] 字符组内的任一字符
[^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)
^[^] 非字符组内的字符开头的行
[a-z] 小写字母
[A-Z] 大写字母
[a-Z] 小写和大写字母
[0-9] 数字
\< 单词头 单词一般以空格或特殊字符做分隔,连续的字符串被当做单词
\> 单词尾
<d>扩展正则 加 -r 参数 或转义
sed -n '/roo\?/p' /etc/passwd
sed -rn '/roo?/p' /etc/passwd
? 前导字符零个或一个
+ 前导字符一个或多个
abc|def abc或def
a(bc|de)f abcf 或 adef
x\{m\} x出现m次
x\{m,\} x出现m次至多次(至少m次)
x\{m,n\} x出现m次至n次
<e>NR变量定址
NR 表示AWK读入的行数
FNR表示读入行所在文件中的行数
# awk '{print NR,FNR,$1}' file1 file2
1 1 aaaaa
2 2 bbbbb
3 3 ccccc
4 1 dddddd
5 2 eeeeee
6 3 ffffff
#
逻辑运算 可直接引用域进行运算
== >= <= != > < ~ !~
# awk 'NR==1 {print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
#
3.命令 {print $0}
4.读后处理 END {awk_cmd1;awk_cmd2;}
<f>AWK变量
NR 当前记录的个数(全部文件连接后的统计)
FNR 当前记录的个数(仅为当前文件的统计,非全部)
FS 字段分隔符 默认为连续空格或制表符,可以使用多个不同的符号做分隔符 -F[:/]
OFS 输出字符的分隔符 默认是空格
# awk -F: 'OFS="=====" {print $1,$2}' /etc/passwd
root=====x
NF 当前读入行的字段个数
ORS 输出记录分隔符 默认是换行
# awk -F: 'ORS="=====" {print $1,$2}' /etc/passwd
root x=====bin x=====
FILENAME 当前文件名
引用shell变量的方法
# a=root
# awk -v var=$a -F: '$1 == var {print $0}' /etc/passwd
或者 把整个命令拆开传递,让shell变量外露,
# awk -F: '$1 == "'$a'" {print $0}' /etc/passwd
# a=NF
# awk -F: '{print $'$a'}' /etc/passwd
操作符
赋值
= += -= /= *=
逻辑与 逻辑或 逻辑非
&& || !
匹配正则或不匹配,正则需要用 /正则/ 包围住
~ !~
关系 比较字符串时要把字符串用双引号引起来
< <= > >= != ==
字段引用
$ 字段引用需要加$,而变量引用直接用变量名取
运算符
+ - * / % ++ --
转义序列
\\ \自身
\$ 转义$
\t 制表符
\b 退格符
\r 回车符
\n 换行符
\c 取消换行
# awk -F: '{if ($1 == "root") print $1;else if ($1 == "seker") print $6;else if ($1 == "zorro") print $7;else print NR}' /etc/passwd root 2 3 ... 33 /home/seker /bin/bash 36 条件 ? 动作1 : 动作2 expr?action1:action2 # awk -F: 'var=($3 >= 500)?$1:"system_user" {print $1"\t"$3"\t"var}' /etc/passwd # awk -F: '{print ($3>500?$1:$2)}' /etc/passwd
常用系统变量
PATH
PWD
LANG
HOME
HISTSIZE
PS1
IFS
域分隔符 是空格,换行,TAB键的合集
算术运算符
+
-
*
/
%
[root@MiWiFi-R3-srv ~]# echo $[3+1]
输出结果:4
part2 关系操作
<
>
<=
>=
==
!=
&&
||
[root@MiWiFi-R3-srv ~]#
[root@MiWiFi-R3-srv ~]# x=1
[root@MiWiFi-R3-srv ~]# [ $x -gt 1 ]
[root@MiWiFi-R3-srv ~]# echo $?
0
part3 赋值运算符
=
+=
*=
/=
%=
#!/bin/bash
var='/etc/init.d'
#var='/dev/sda'
if多分支
if (条件) 动作
若有多个动作,则要用大括号将动作体包含起来 if (条件) {动作1;动作2}
# awk -F: '{if ($1 == "root") print $1}' /etc/passwd
root
#
# awk -F: '{if ($1 == "root") {print $1;print $6}}' /etc/passwd
root
/root
#
if (条件1)
动作1
else
动作2
# awk -F: '{if ($1 == "root"){print $1}else print $6}' /etc/passwd
# awk -F: '{if ($1 == "root") print $1;else print $6}' /etc/passwd
上面两个命令是等价的,要么用分号隔开,表示第一个动作体的结束,要么将动作体用大括号定位范围
if (条件 1)
动作1
else if(条件 2)
动作2
else if(条件 3)
动作3
else
动作4
# awk -F: '{if ($1 == "root") print $1;else if ($1 == "seker") print $6;else if ($1 == "zorro") print $7;else print NR}' /etc/passwd
root
2
3
...
33
/home/seker
/bin/bash
36
条件 ? 动作1 : 动作2
expr?action1:action2
# awk -F: 'var=($3 >= 500)?$1:"system_user" {print $1"\t"$3"\t"var}' /etc/passwd
# awk -F: '{print ($3>500?$1:$2)}' /etc/passwd
if [ -d $var ] then echo "$var is directory" elif [ -b $var ] then echo "$var is block" elif [ -f $var ] then echo "$var is regular file" else echo 'unknow' fi
二:awk文本处理
打印uid在30~40范围内的用户名。
awk -F: '$3 >=30 && $3<=40 {print $1}' passwd
打印第5-10行的行号和用户名
awk -F: 'NR>=5 && NR<=10{print NR,$1}' passwd
打印奇数行
[root@python_lb yan]# awk -F: '{if(NR%2==1) print $0}' passwd
打印偶数行
[root@python_lb yan]#awk -F: '{if(NR%2==0) print $0}' passwd
打印字段数大于5的行
[root@python_lb yan]# awk -F: 'NF>5{print $0}' passwd
打印UID不等于GID的用户名
awk -F: '$3!=$4{print $1}' passwd
打印没有指定shell的用户
awk -F: '$7==""{print $1}' passwd
三:shell脚本编写
自动部署、初始配置、并启动nginx反向代理服务
systemctl stop firewalld.service
setenforce 0
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/sysconfig/selinux
iptables -F
yum install -y epel-release
yum install -y nginx
systemctl start nginx.service
监控脚本:监控每台机器的内存使用率>70%,则输出报警信息
(思路提示:
[root@www ~]# ((80>70))
[root@www ~]# echo $?
0
)
#!/bin/bash
mem_total=`free |awk 'NR==2{print $2}'`
mem_userd=`free|awk 'NR==2{print $3}'`
mem_per=`echo "scale=2;${mem_userd}/${mem_total}"|bc -l|cut -d. -f2`
if [ $mem_per -gt 70 ]
then
echo "警报信息"
else
echo "正常"
fi
)