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


相关文章
|
5天前
|
Shell Linux
【linux】Shell脚本中basename和dirname的详细用法教程
本文详细介绍了Linux Shell脚本中 `basename`和 `dirname`命令的用法,包括去除路径信息、去除后缀、批量处理文件名和路径等。同时,通过文件备份和日志文件分离的实践应用,展示了这两个命令在实际脚本中的应用场景。希望本文能帮助您更好地理解和应用 `basename`和 `dirname`命令,提高Shell脚本编写的效率和灵活性。
58 32
|
4月前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
150 1
|
3月前
|
Shell Linux Windows
让我们熟悉一下 shell 正则表达式使用
正则表达式是一种文本处理工具,用于匹配、查找、替换或提取字符串中的特定模式。通过普通字符和特殊字符(元字符)组成,定义匹配规则。本文档通过示例展示了如何使用正则表达式进行字符串搜索、过滤和模式匹配,包括基本匹配、行首行尾定位、字符集使用、任意字符与重复字符处理以及限定重复次数等高级功能。
73 7
|
3月前
|
Shell Linux 测试技术
6种方法打造出色的Shell脚本
6种方法打造出色的Shell脚本
103 2
6种方法打造出色的Shell脚本
|
3月前
|
XML JSON 监控
Shell脚本要点和难点以及具体应用和优缺点介绍
Shell脚本在系统管理和自动化任务中扮演着重要角色。尽管存在调试困难、可读性差等问题,但其简洁高效、易于学习和强大的功能使其在许多场景中不可或缺。通过掌握Shell脚本的基本语法、常用命令和函数,并了解其优缺点,开发者可以编写出高效的脚本来完成各种任务,提高工作效率。希望本文能为您在Shell脚本编写和应用中提供有价值的参考和指导。
125 1
|
3月前
|
Ubuntu Shell 开发工具
ubuntu/debian shell 脚本自动配置 gitea git 仓库
这是一个自动配置 Gitea Git 仓库的 Shell 脚本,支持 Ubuntu 20+ 和 Debian 12+ 系统。脚本会创建必要的目录、下载并安装 Gitea,创建 Gitea 用户和服务,确保 Gitea 在系统启动时自动运行。用户可以选择从官方或小绿叶技术博客下载安装包。
125 2
|
4月前
|
监控 网络协议 Shell
ip和ip网段攻击拦截系统-绿叶结界防火墙系统shell脚本
这是一个名为“小绿叶技术博客扫段攻击拦截系统”的Bash脚本,用于监控和拦截TCP攻击。通过抓取网络数据包监控可疑IP,并利用iptables和firewalld防火墙规则对这些IP进行拦截。同时,该系统能够查询数据库中的白名单,确保合法IP不受影响。此外,它还具备日志记录功能,以便于后续分析和审计。
84 6
|
3月前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
4月前
|
监控 Unix Shell
shell脚本编程学习
【10月更文挑战第1天】shell脚本编程
103 12
|
4月前
|
存储 运维 监控
自动化运维:使用Shell脚本简化日常任务
【9月更文挑战第35天】在IT运维的日常工作中,重复性的任务往往消耗大量的时间。本文将介绍如何通过编写简单的Shell脚本来自动化这些日常任务,从而提升效率。我们将一起探索Shell脚本的基础语法,并通过实际案例展示如何应用这些知识来创建有用的自动化工具。无论你是新手还是有一定经验的运维人员,这篇文章都会为你提供新的视角和技巧,让你的工作更加轻松。
133 2