Shell 脚本正则表达式(三)

简介: Shell 脚本正则表达式

Shell 脚本正则表达式(三)



一、Awk 工具概述


1.Awk 工作流程

2.Awk 常见用法

3.Awk 的变量

4.Awk 区块原理


二、Awk 用法示例


1)按行输出文本

2)按字段输出文本

3)通过管道、双引号调用 Shell 命令

4)printf 的使用

5)Awk 常见的模式类型

6)匹配范围


三、Awk 高级用法


1.if-else 判断

2.while 循环

3. for 循环

4.数组


一、Awk 工具概述



Awk 是一种编程语言,用于在 Linux 或 Unix 下对文件和数据进行处理。简单来说就是 Awk 把文件逐行的读入,以空格为默认分隔符将每行数据切片,切开的部分再进行各种分析处理。擅长取行、取列、过滤。


  • Awk 处理过程:依次对每一行进行处理,然后输出。


1.Awk 工作流程


示例:


awk -F ':' '{print $1,$3,$4}' /etc/passwd


image.png


  1. Awk 命令会逐行读取文件的内容进行处理。
  2. Awk 以 : 为分隔符,将第 1 行数据格式化为 7 段,每段数据存入 $1-$7 变量中。$0 存储这 1 行数据。
  3. 一行处理完成才会继续处理下一行,直到此文件读取结束。


2.Awk 常见用法


awk 选项  '模式 { 动作 (action) }' 文件1 文件2 …
awk  -f  脚本文件 文件1 文件2 …


  • 选项:-F 指定输入分隔符,可以是字符串或正则表达式。(如果不加 -F 则默认以空格作为分隔符)
  • 最常见的动作:print、printf


3.Awk 的变量


Awk 变量:


image.png


输出前 3 行的第 1 字段


[root@localhost ~]# head -3 /etc/passwd | awk 'BEGIN {FS=":"}{print $1}'


image.png


将 x 作为行分隔符来输出前 3 行


[root@localhost ~]# head -3 /etc/passwd | awk 'BEGIN {RS="x"}{print $1}'


image.png


指定列与列之间的分隔符,并输出第 1 字段和第 7 字段


[root@localhost ~]# head -3 /etc/passwd | awk -F: '{OFS="--"}{print $1,$7}'


image.png


指定行与行之间的分隔符,并输出第 1 字段


image.png


Awk 内建变量:


image.png


输出网卡接口每行的字段数


[root@localhost ~]# ifconfig ens32 | awk '{print NF}'


image.png


NR 和 NFR 对比


image.png


4.Awk 区块原理


区域构成:


BEGIN { 动作 }            #开始处理第一行之前的操作
{ 动作 }              #针对每一行的处理操作
END { 动作 }            #处理完最后一行之后的操作


执行流程:


  1. 首先执行 BEGIN { } 区块中的初始化操作;
  2. 然后从指定的数据文件中循环读取一个数据行(自动更新 NF、NR、$0、$1 … 等内建变量的值),并执行 ‘模式或条件{ 动作 }’;
  3. 最后执行 END { } 区块中的后续处理操作。


二、Awk 用法示例



创建测试文件


[root@localhost ~]# vim test.txt
he was short and fat.
He was wearing a blue polo shirt with black pants.
The home of Football on BBC Sport online.
the tongue is boneless but it breaks bones.12!
google is the best tools for search keyword.
The year ahead will test our political establishment to the li
PI=3.141592653589793238462643383249901429
a wood cross!
Actions speak louder than words
#woood #
#woooooood #
AxyzxyzxyzxyzC
I bet this place is really spooky late at night!
Misfortunes never come alone/single.
I shouldn't have lett so tast.


1)按行输出文本


输出所有内容等同于 cat test.txt


[root@localhost ~]# awk '{print}' test.txt
[root@localhost ~]# awk '{print $0}' test.txt


image.png


输出1-3 行内容


[root@localhost ~]# awk 'NR==1,NR==3{print}' test.txt
[root@localhost ~]# awk '(NR>=1)&&(NR<=3){print}' test.txt


image.png


输出奇数行(%2 求模运算,余数为 1 是奇数,0 为偶数)


[root@localhost ~]# awk '(NR%2)==1{print}' test.txt


输出偶数行


[root@localhost ~]# awk '(NR%2)==0{print}' test.txt


image.png


输出以 root 开头的行


[root@localhost ~]# awk '/^root/{print}' /etc/passwd


image.png


输出以 bash 结尾的行


[root@localhost ~]# awk '/bash$/{print}' /etc/passwd


image.png


统计以 /bin/bash 结尾的行


[root@localhost ~]# awk 'BEGIN {A=0};/\/bin\/bash$/{A++};END {print A}' /etc/passwd
[root@localhost ~]# awk -F : '$7=="/bin/bash"{print NR}' /etc/passwd


image.png


统计以空行分割的文本段落数


[root@localhost ~]# awk 'BEGIN{RS=""};END{print NR}' /etc/sysctl.conf


image.png


2)按字段输出文本


输出每行中以空格或制表位分割的第 3 个字段


[root@localhost ~]# awk '{print $3}' test.txt


image.png


输出第 1,3 字段


[root@localhost ~]# awk '{print $1,$3}' test.txt


image.png


输出密码为空的行


[root@localhost ~]# awk -F : '$2==""{print}' /etc/shadow
[root@localhost ~]# useradd zhangsan            #创建zhangsan用户
[root@localhost ~]# passwd -d zhangsan            #清空zhangsan用户密码
[root@localhost ~]# awk -F : '$2==""{print}' /etc/shadow
[root@localhost ~]# awk 'BEGIN{FS=":"};$2==""{print}' /etc/shadow


image.png


输出以 : 分割,第7字段包含 /bash,的行的第 1 个字段


[root@localhost ~]# awk -F: '$7~"/bash"{print $1}' /etc/passwd


image.png


输出第 1 个字段包含 nfs;并且等于 8 个字段的行的第 1,2 字段


[root@localhost ~]# awk '($1~"nfs")&&(NF==8){print $1,$2}' /etc/services


image.png


输出第 7 个字段不是 /bin/bsh 也不是 /sbin/nologin 的行


[root@localhost ~]# awk -F: '($7!="/bin/bsh")&&($7!="/sbin/nologin"){print}' /etc/passwd


image.png


3)通过管道、双引号调用 Shell 命令


调用 wc -l 命令统计使用 bash 的用户个数


[root@localhost ~]# awk -F: '/bash$/{print | "wc -l"}' /etc/passwd
[root@localhost ~]# grep -c "bash$" /etc/passwd


image.png


调用 w 命令,统计在线用户数


  • getline 函数:一次读取一行数据,若读取成功则返回值 1,若读取失败则返回值 -1,若遇到文件结束(EOF),则返回值 0。


[root@localhost ~]# awk 'BEGIN {while ("w"|getline)n++;{print n-2}}'


image.png


调用 hostname,并输出当前主机名


[root@localhost ~]# awk 'BEGIN {"hostname"|getline;print $0}'


image.png


4)printf 的使用


  • 格式:printf "格式",列表1,列表2 …


特征:


  • A:必须指定 format(格式),用于指定后面 item(列表) 的输出格式。
  • B:printf 语句不会自动打印 \n(换行符)。
  • C:format 格式以 % 加一个字符。


image.png


  • d:修饰符;N:显示宽度;-:左对齐(默认是右对齐);+:显示数值符号。


示例:


[root@localhost ~]# awk -F : '{printf "%-20s%-10d%-10s\n",$1,$2,$7}' /etc/passwd


image.png


[root@localhost ~]# awk -F: 'BEGIN {printf "%-20s%-10s%-15s\n","UserName","ID","Shell"}{printf "%-20s%-10s%-15s\n",$1,$3,$7}' /etc/passwd


image.png


5)Awk 常见的模式类型


  • 正则表达式(regexp):awk -F : '/^r/{print $1}' /etc/passwd
  • 表达式(expression):值为非 0 或为非空是满足条件的,如 $1 ~/foo/ 或 $1 == "root"


输出普通用户


[root@localhost ~]# awk -F: '$3>=1000{print $1,$3,$7}' /etc/passwd


image.png


输出 UID 在 10-100 之间的用户


[root@localhost ~]# awk -F: '$3+1<=99 && $3+1>=10{print $1,$3,$7}' /etc/passwd


image.png


检查未初始化密码的用户


[root@localhost ~]# awk -F: '$2=="!!"{print $1,$2}' /etc/shadow


image.png


6)匹配范围


查询 UID 为 3 到 10 之内的用户


[root@localhost ~]# awk -F: '$3==3,$3==10{print $1,$3,$7}' /etc/passwd


image.png


[root@localhost ~]# awk -F: '$1=="root",$1=="adm"{print $1,$3,$7}' /etc/passwd


image.png


三、Awk 高级用法



1.if-else 判断


  • 语法:if (条件表达式) 命令 操作1;else 命令 操作2


输出第七列包含 bash,如果第一列是 root 打印 管理员,否则打印出第一列 和 普通用户


[root@localhost ~]# awk -F: '$7~"bash"{if ($1=="root")print $1,"管理员";else print $1,"普通用户"}' /etc/passwd


image.png


输出普通用户的数量


[root@localhost ~]# awk -F: -v A=0 '{if ($3>=1000) A++}END{print A}' /etc/passwd


image.png


使用 printf 打印


[root@localhost ~]# awk -F: '$7~"bash$"{if ($1=="root") printf "%-15s: %s\n",$1,"管理员";else printf "%-15s: %s\n",$1,"普通用户"}' /etc/passwd


image.png


image.png


2.while 循环


  • 语法:while (条件){语句1;语句2; ...


循环打印前 3 列


[root@localhost ~]# head -3 /etc/passwd | awk -F : '{A=1;while (A<=3){print $A;A++}}'


image.png


[root@localhost ~]# head -3 /etc/passwd | awk -F: '{print $1"\n"$2"\n"$3}'


image.png


循环整行并打印出长度小于 4 的字段


  • length 函数:返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。


[root@localhost ~]# head -3 /etc/passwd | awk -F: '{A=1;while (A<NF){if (length($A) <= 4) print $A;A++}}'


image.png


3. for 循环


  • 语法:for (初始变量;条件;变量 自加){语句1,语句2, ...}


循环打印前 3 列


[root@localhost ~]# head -3 /etc/passwd | awk -F: '{for(A=1;A<=3;A++) print $A}'


image.png


4.数组


Awk 的数组,是一种关联数组(Associative Arrays),下标可以是数字和字符串。因无需对数组名和元素提前声明,也无需指定元素个数 ,所以 Awk 的数组使用非常灵活。


  1. 不需要正式定义,一个数组在使用时被定义;
  2. 数组元素的初始值为 0 或空字符串,除非他们被显示的指定初始化;
  3. 数组可以自动扩展;
  4. 下标可以使字符串。


语法结构:数组名[下标]


统计网络连接数中的每种状态的个数


[root@localhost ~]# netstat -ant | awk '/^tcp/{A[$6]++}END{for (B in A){print B,A[B]}}'


image.png


相关文章
|
3天前
|
分布式计算 Hadoop Shell
使用shell脚本实现自动SSH互信功能
使用shell脚本实现自动SSH互信功能
10 1
|
4天前
|
Unix Shell Linux
轻松编写 AIX Shell 脚本
轻松编写 AIX Shell 脚本
11 1
|
4天前
|
监控 关系型数据库 Shell
Shell脚本入门:从基础到实践,轻松掌握Shell编程
Shell脚本入门:从基础到实践,轻松掌握Shell编程
|
5天前
|
关系型数据库 MySQL Shell
在Centos7中利用Shell脚本:实现MySQL的数据备份
在Centos7中利用Shell脚本:实现MySQL的数据备份
|
6天前
|
Shell Linux 编译器
C语言,Linux,静态库编写方法,makefile与shell脚本的关系。
总结:C语言在Linux上编写静态库时,通常会使用Makefile来管理编译和链接过程,以及Shell脚本来自动化构建任务。Makefile包含了编译规则和链接信息,而Shell脚本可以调用Makefile以及其他构建工具来构建项目。这种组合可以大大简化编译和构建过程,使代码更易于维护和分发。
24 5
|
7天前
|
Shell 程序员 数据安全/隐私保护
shell 脚本 if-else判断 和流程控制 (基本语法|基础命令)
shell 脚本 if-else判断 和流程控制 (基本语法|基础命令)
|
7天前
|
存储 Shell C语言
shell脚本 编程 变量 基本入门(详解)
shell脚本 编程 变量 基本入门(详解)
|
7天前
|
Shell Linux 编译器
C语言,Linux,静态库编写方法,makefile与shell脚本的关系。
总结:C语言在Linux上编写静态库时,通常会使用Makefile来管理编译和链接过程,以及Shell脚本来自动化构建任务。Makefile包含了编译规则和链接信息,而Shell脚本可以调用Makefile以及其他构建工具来构建项目。这种组合可以大大简化编译和构建过程,使代码更易于维护和分发。
15 3
|
13天前
|
弹性计算 运维 监控
|
13天前
|
存储 弹性计算 运维
自动化收集员工信息的Shell脚本
【4月更文挑战第30天】
11 0