grep
grep命令主要对文本的(正则表达式)行基于模式进行过滤
作用: 文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查,打印匹配到的行
模式: 由正则表达式字符及文本字符所编写的过滤条件
格式:
grep [OPTIONS] PATTERN [FILE...]
常用选项:
--color=auto: 对匹配到的文本着色显示
-v: 显示不被pattern匹配到的行
-i: 忽略字符大小写
-n:显示匹配的行号
-c: 统计匹配的行数
-o: 仅显示匹配到的字符串
-q: 静默模式,不输出任何信息
-A #: after, 后#行
-B #: before, 前#行
-C #:context, 前后各#行
-e:实现多个选项间的逻辑or关系,如 grep –e ‘cat ’ -e ‘dog’ file
-w:匹配整个单词
-E:使用ERE,相当于egrep
-F:相当于fgrep,不支持正则表达式
-P: 支持Perl格式的正则表达式
-f file: 根据模式文件处理
-r: 递归目录,但不处理软连接
-R: 递归目录,处理软连接
sed
stream editor,文本编辑工具
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。
功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等用法:
sed [option]... 'script;script;...' [inputfile...]
常用选项:
-n:不输出模式空间内容到屏幕,即不自动打印
-e: 多点编辑
-f:/PATH/SCRIPT_FILE : 从指定文件中读取编辑脚本
-r,-E: 支持使用扩展正则表达式
-i.bak: 备份文件并原处编辑
#说明
-ir 不支持
-i -r 支持
-ri 支持
-ni 危险选项,会清空文件
script格式:
'地址命令'
地址格式:
1、不给地址:对全文进行处理
2、单地址:
#: 指定的行,$:最后一行
/pattern/: 被此处模式所能够匹配到的每一行
3、地址范围:
#,#
#,+#
/pat1/,/pat2/
#,/pat/
/pat/,#
4、步进:~
1~2 奇数行
2~2 偶数行
命令:
d: 删除模式空间匹配的行,并立即启用下一轮循环
p:打印当前模式空间内容,追加到默认输出之后
Ip: 忽略大小写输出
a [\]text:在指定行后面追加文本,支持使用\n实现多行追加
i [\]text:在行前面插入文本
c [\]text:替换行为单行或多行文本
w /path/somefile: 保存模式匹配的行至指定文件
r /path/somefile:读取指定文件的文本至模式空间中匹配到的行后
=: 为模式空间中的行打印行号
!: 模式空间中匹配行取反处理
q 结束或退出sed
查找替代
s/pattern/string/修饰符 查找替换,支持使用其他分隔符,可以使其他形式: s@@@,s###
替换修饰符:
g: 行内全局替换
p: 显示替换成功的行
w /PATH/TO/SOMEFILE :将替换成功的行保存至文件中
I,i 忽略大小写
awk
linux上的实现gawk,文本报告生成器
格式:
awk [参数] '[动作]' [文件名]
awk [参数] –f 动作文件 var=value [文件名]
awk [参数] 'BEGIN段 [动作] END段' [文件名]
注意:
动作的格式 '匹配条件{打印动作}'
常见参数:
-F 指定列的分隔符,默认一行数据的列分隔符是空格
-f file 指定读取程序的文件名
-v var=value 自定义变量
awk程序运行优先级是:
1 BEGIN: 在开始处理数据流之前执行,可选项
2 动作: 如何处理数据流,必选项
3 END: 处理完数据流后执行,可选项
常见动作
print 显示内容
$0 显示当前行所有内容
$n 显示当前行的第n列内容,如果存在多个$n,它们之间使用逗号(,)隔开
注意:
如果打印的内容是变量,则无需在变量两侧加上双引号,其他的都应该加双引号
常见内置变量
FILENAME 当前输入文件的文件名,该变量是只读的
NR 指定显示行的行号
FNR 多文件时候,分别计数
NF 表示字段数量
OFS 输出格式的列分隔符,缺省是空格
FS 输入文件的列分隔符,缺省是连续的空格和Tab
RS 输入记录分隔符,指定输入时的换行符,原换行符($)仍有效
ORS 输出记录分隔符,输出时用指定符号代替换行符
ARGC|ARGV[n] 获取命令的参数个数|参数内容
字段提取:提取一个文本中的一列数据并打印输出,它提供了相关的内置变量
$0 表示整行文本
$1 表示文本行中的第一个数据字段
$2 表示文本行中的第二个数据字段
$N 表示文本行中的第N个数据字段
$NF 表示文本行中的最后一个数据字段
NR 代表行的行号,在动作外部表示特定行
注意:
如果打印多列信息,需要使用逗号隔开,否则是内容合并
awk示例
1、基础示例
# 示例文件
cat awk.txt
nihao awk1 awk2 awk3
nihao awk4 awk5 awk6
nihao awk7 awk8 awk9
打印第1列的内容
# awk '{print $1}' awk.txt
nihao
nihao
nihao
打印最后一列信息
# awk '{print $NF}' awk.txt
awk3
awk6
awk9
打印所有内容
# awk '{print $0}' awk.txt
nihao awk1 awk2 awk3
nihao awk4 awk5 awk6
nihao awk7 awk8 awk9
打印第3,8列内容
# awk '{print $1,$3}' awk.txt
nihao awk2
nihao awk5
nihao awk8
打印信息时候,合并信息
# awk '{print $1$3}' awk.txt
nihaoawk2
nihaoawk5
nihaoawk8
使用\t实现内容的分割,需要用""扩住
# awk '{print $1"\t"$3}' awk.txt
nihao awk2
nihao awk5
nihao awk8
打印列外普通信息
# awk '{print "hello awk"}' awk.txt
hello awk
hello awk
hello awk
注意:
如果没有$n的话,表示 print动作执行的次数与文件行数一致
打印fstab的关键信息
# grep "^UUID" /etc/fstab |awk {'print $1,$3'}
UUID=5583bd7c-cc9f-4e19-b453-c224102f3ed5 xfs
UUID=cbd246cd-1df8-4fe7-9040-823cd0978837 xfs
打印每列的行号信息
# awk '{print NR,$0}' awk.txt
1 nihao awk1 awk2 awk3
2 nihao awk4 awk5 awk6
3 nihao awk7 awk8 awk9
按照行号打印对应列的内容
# awk '{print NR, $NR}' awk.txt
1 nihao
2 awk4
3 awk8
制定行号打印信息
# awk 'NR==1 {print NR,$1,$3}' awk.txt
1 nihao awk2
# awk 'NR==2 {print NR,$1,$3}' awk.txt
2 nihao awk5
2、进阶示例
awk默认的信息查看是以空格作为列分隔符的,而对于非空格作为分隔符的内容,我们需要借助于专门的语法实现信息的分割,这里主要用到以下知识:
常见参数:
-F 指定列的分隔符,默认一行数据的列分隔符是空格
常见内置变量
FS 输入文件的列分隔符,缺省是连续的空格和Tab
RS 输入记录分隔符,指定输入时的换行符,原换行符($)仍有效
注意:
一般情况下,在输出信息之前进行格式的调整,需要在BEGIN{}部分设定
准备文件内容
# head -n1 /etc/passwd > passwd.txt
# cat passwd.txt
root:x:0:0:root:/root:/bin/bash
使用普通awk命令展示
[root@rocky9 ~]# awk '{print $1}' passwd.txt
root:x:0:0:root:/root:/bin/bash
[root@rocky9 ~]# awk '{print $2}' passwd.txt
[root@rocky9 ~]# awk '{print $0}' passwd.txt
root:x:0:0:root:/root:/bin/bash
结果显示:
文件中只有一列,无法被awk默认分离
设定分隔符实现信息的分隔效果
[root@rocky9 ~]# awk -F ':' '{print $0}' passwd.txt
root:x:0:0:root:/root:/bin/bash
[root@rocky9 ~]# awk -F ':' '{print $1}' passwd.txt
root
[root@rocky9 ~]# awk -F ':' '{print $1,$2}' passwd.txt
root x
[root@rocky9 ~]# awk -F ':' '{print $1,$7}' passwd.txt
root /bin/bash
基于-v方式设定输入分隔符的环境变量FS
[root@rocky9 ~]# awk -v FS=":" '{print $1FS$7}' passwd.txt
root:/bin/bash
虽然-v FS 和 -F 都可以设定入口数据的列分隔符,如果混用的话,-F的优先级高一点
获取网址域名信息
[root@rocky9 ~]# cat domain.txt
http://www.example.org/index.html
http://www.example.org/1.html
http://api.example.org/index.html
http://upload.example.org/index.html
http://img.example.org/3.html
http://search.example.org/2.html
对相关信息进行统计
[root@rocky9 ~]# awk -F[/]+ '{print $2}' domain.txt | uniq -c
2 www.sswang.org
1 api.sswang.org
1 upload.sswang.org
1 img.sswang.org
1 search.sswang.org
[root@rocky9 ~]# awk -F[/]+ '{print $(NF-1)}' domain.txt | uniq -c
2 www.sswang.org
1 api.sswang.org
1 upload.sswang.org
1 img.sswang.org
1 search.sswang.org
awk支持格式化输出相关信息。它主要依赖两种方法:
属性方法
OFS 输出格式的列分隔符,缺省是空格
ORS 输出记录分隔符,输出时用指定符号代替换行符
print方法
printf [-v var] format [item1,item2,...]
注意:
printf输出需要指定换行符号,format的格式必须与后面item对应
常见格式:
%c 显示字符的ASCII码 %d|i 显示十进制整数
%e|E 显示科学计数法数值 %u 显示无符号整数
%f 显示浮点数 %s 显示字符串
%% 显示%本身
修饰符:
%#[.#] 第一个#控制显示宽度,第二个#表示小数点后的精度,例如%3.1f
%- 左对齐,%-15s
%+ 显示数值的正负符号,%+d
列输出分隔符实践
借助于-v方式为命令行输出相关信息
[root@rocky9 ~]# awk -F ':' -v OFS="~~~" '{print $1,$7}' passwd.txt
root~~~/bin/bash
借助于BEGIN语句设定环境变量
[root@rocky9 ~]# awk -F":" 'BEGIN{OFS="~"} {print NR,$1,$7}' passwd.txt
1~root~/bin/bash
在BEGIN内部同时实现多个环境变量
[root@rocky9 ~]# awk 'BEGIN{FS=":";OFS="-"}NR==1{print $1,$3,$NF}' passwd.txt
root-0-/bin/bash
行输入输出分隔符实践
定制输入分隔符
[root@server12 ~]# seq 7 | awk 'BEGIN{RS=""}{print $1,$2,$3,$4,$5,$6,$7}'
1 2 3 4 5 6 7
借助于-v方式为行分隔符输出相关信息
[root@rocky9 ~]# awk -F ':' -v ORS="|" '{print $NR,$0}' awk.txt
nihao awk1 awk2 awk3 nihao awk1 awk2 awk3| nihao awk4 awk5 awk6| nihao awk7 awk8 awk9|[root@rocky9 ~]#
借助于BEGIN语句设定环境变量
[root@rocky9 ~]# awk -F":" 'BEGIN{ORS="|"} {print NR,$0}' awk.txt
1 nihao awk1 awk2 awk3|2 nihao awk4 awk5 awk6|3 nihao awk7 awk8 awk9|[root@rocky9~]#
printf格式化输出实践
使用print的格式信息
[root@rocky9 ~]# awk '{printf "%s\n",$1}' awk.txt
nihao
nihao
nihao
[root@rocky9 ~]# awk '{printf "%s",$1}' awk.txt; echo
nihaonihaonihao
多信息格式化嵌套
[root@rocky9 ~]# awk '{printf "%d--%s--%s\n", NR,$1,$NR}' awk.txt
1--nihao--nihao
2--nihao--awk4
3--nihao--awk8
数字的格式化输出
[root@rocky9 ~]# awk '{printf "%4.2f--%s\n", NR,$1}' awk.txt
1.00--nihao
2.00--nihao
3.00--nihao
字符的格式化输出
[root@rocky9 ~]# awk '{printf "%-8s%s\n", NR,$1}' awk.txt
1 nihao
2 nihao
3 nihao
3、awk优先级示例
awk为了体现程序的逻辑顺序,划分了三个代码段,其结构如下:
格式显示:
BEGIN{}: 读入第一行文本之前执行的语句,一般用来初始化操作
{}: 逐行处理的执行命令
END{}: 处理完最后以行文本后执行,一般用来处理输出结果
BEGIN设定数据处理的前置准备
[root@rocky9 ~]# awk 'BEGIN{OFS=":"} {print NR,$0}' awk.txt
1:nihao awk1 awk2 awk3
2:nihao awk4 awk5 awk6
3:nihao awk7 awk8 awk9
{}定制输出的内容样式
[root@rocky9 ~]# awk '{ print "第一列:"$1,"第二列:"$2 }' awk.txt
第一列:nihao 第二列:awk1
第一列:nihao 第二列:awk4
第一列:nihao 第二列:awk7
END设定信息处理完毕后的收尾动作
[root@rocky9 ~]# awk 'END{printf "----------------\n行数总计: %2d\n", NR}' awk.txt
----------------
行数总计: 3
[root@rocky9 ~]# awk -F: 'BEGIN{print "begin中的NR值:" NR} NR==11 {print "命令中的NR值: " NR}END{print "END中的NR值: " NR}' /etc/passwd
begin中的NR值:0
命令中的NR值: 11
END中的NR值: 23
结果可知:
begin的优先级 > 命令优先级 > END的优先级
BEGIN 和 {} 实现信息的头部格式化
[root@rocky9 ~]# awk 'BEGIN{print "第一列\t第二列\n----------------"}{print $1"\t"$2}' awk.txt
第一列 第二列
----------------
nihao awk1
nihao awk4
nihao awk7
完全组合实现信息的头部和尾部格式化操作
[root@rocky9 ~]# awk 'BEGIN{print "第一列\t第二列\n----------------";total=0;} {print $1"\t"$2;total = NR}END{printf "----------------\n行数总计: %2d\n", total}'
awk.txt
第一列 第二列
----------------
nihao awk1
nihao awk4
nihao awk7
----------------
行数总计: 3
统计文件格式化
[root@rocky9 ~]# awk -F":" 'BEGIN{printf "---------------------------\n%-12s|%9s|\n---------------------------\n","用户名","shell类型"}{printf "%-15s|%10s|\n---------------------------\n",$1,$7}END{printf "用户总数总: %2d\n",NR}' passwd.txt
---------------------------
用户名 | shell类型|
---------------------------
root | /bin/bash|
---------------------------
用户总数总: 1
定制配置考试成果表
[root@rocky9 ~]# cat course_scores.txt
张三 100 56 99
李四 90 68 89
王五 50 78 67
赵六 80 99 89
格式化显示
[root@rocky9 ~]# awk 'BEGIN{printf "----------------------\n|%-3s|%2s|%2s|%2s|\n----------------------\n","姓名","语文","数学","历史";} NR>=1 {printf"|%-3s|%4d|%4d|%4d|\n",$1,$2,$3,$4} END{printf "----------------------\n学生 总数总: %2d\n", NR}' course_scores.txt
----------------------
|姓名 |语文|数学|历史|
----------------------
|张三 | 100| 56| 99|
|李四 | 90| 68| 89|
|王五 | 50| 78| 67|
|赵六 | 80| 99| 89|
----------------------
学生总数总: 4
4、awk变量示例
awk所支持的变量主要有两种类型:内置变量和自定义变量
内置变量
所谓的内置变量主要就是awk内部已经定制好的变量,我们可以直接拿过来使用,这些常见的方法我们基本上都演示过了,比如:
FILENAME 当前输入文件的文件名,该变量是只读的
FIELDWIDTHS 以空格分隔的数字列表,用空格定义每个数据字段的精确宽度
NR 指定显示行的行号
FNR 多文件时候,分别计数
NF 表示字段数量
OFS 输出格式的列分隔符,缺省是空格
FS 输入文件的列分隔符,缺省是连续的空格和Tab
RS 输入记录分隔符,指定输入时的换行符,原换行符($)仍有效
ORS 输出记录分隔符,输出时用指定符号代替换行符
ARGC|ARGV[n] 获取命令的参数个数|参数内容
自定义变量
主要是根据实际情况,自己定义一些所谓的变量,然后再awk逻辑操作的过程中作为辅助性的措施。自定义变量的定制方法:
-v var=value
它可以在 命令行、BEGIN、{}、END 等位置进行使用
NF 查看当前所在目录
[root@rocky9 ~]# echo $PWD | awk -F / '{print $NF}'
root
[root@rocky9 ~]# cd /etc/sysconfig/
[root@rocky9 /etc/sysconfig]# echo $PWD | awk -F / '{print $NF}'
sysconfig
查看文件名称
[root@rocky9 ~]# echo /etc/sysconfig/network-scripts/ifcfg-eth0 | awk -F / '{print $NF}'
ifcfg-eth0
查看文件所在路径
[root@rocky9 ~]# echo /etc/sysconfig/network-scripts/ifcfg-eth0 | awk -F / '{print $(NF-1)}'
network-scripts
快速获取ip地址
[root@rocky9 ~]# ifconfig eth0 | awk 'NR==2{print $2}'
10.0.0.12
[root@rocky9 ~]# ifconfig eth0 | awk '/netmask/{print $2}'
10.0.0.12
快速获取文件行数
[root@rocky9 ~]# awk -F: 'END{print NR}' /etc/passwd
23
FNR 和 FILENAME 获取文件基本信息
获取文件基本信息
[root@rocky9 ~]# awk '{print FNR,FILENAME,$0}' /etc/issue /etc/redhat-release
1 /etc/issue \S
2 /etc/issue Kernel \r on an \m
3 /etc/issue
1 /etc/redhat-release CentOS Linux release 7.9.2009 (Core)
解析:
FNR 获取文件内容,同时在前面增加行号
FILENAME 获取文件名称
5、awk参数示例
ARGC 获取命令行参数的个数,包括awk命令
[root@rocky9 ~]# awk 'NR==1 {print ARGC }' awk.txt
2
ARGV:将命令行所有参数放到一个数组中,ARGV[下标] 获取所有参数
[root@rocky9 ~]# awk 'NR==1 {print ARGV[0] }' awk.txt
awk
[root@rocky9 ~]# awk 'NR==1 {print ARGV[1] }' awk.txt
awk.txt
变量实践
[root@rocky9 ~]# awk -v name='shuji' 'BEGIN{print name}'
shuji
[root@rocky9 ~]# awk 'BEGIN{name="shuji";print name}'
shuji
定制格式化输出
[root@rocky9 ~]# awk -F: '{age=36; address="beijing";print $1,age,address}'
passwd.txt
root 36 beijing
6、awk赋值运算示例
awk的表达式包括很多种类,常见的表达式有:
算术操作符:+ - * / ^ %
赋值操作符:= += -= /= ++ -- %= ^=
比较操作符:== != > >= < <=
模式匹配符:~ 左边是否与右边匹配包含,!~ 是否不匹配
逻辑操作符:与&&、或||、非!
字符串赋值
[root@rocky9 ~]# awk -v name='shuji' 'BEGIN{print name}'
shuji
[root@rocky9 ~]# awk 'BEGIN{school="xigongda";print school}'
xigongda
数据赋值
命令区域段内进行数据赋值操作
[root@rocky9 ~]# echo | awk '{i=10;print i+=1}'
11
[root@rocky9 ~]# echo | awk '{i=10;print i++,i}'
10 11
[root@rocky9 ~]# echo | awk '{i=10;print ++i,i}'
11 11
在BEGIN段是可以的,由于END段主要是收尾的信息显示,所以基本不做计算层次的功能
[root@rocky9 ~]# awk 'BEGIN{i=0;print i++,i}'
0 1
[root@rocky9 ~]# awk 'BEGIN{i=0;print ++i,i}'
1 1
变量赋值-拓展【真假非】
-v 设定变量进行赋值操作
[root@rocky9 ~]# awk -v n=0 'n++' awk.txt
nihao awk4 awk5 awk6
nihao awk7 awk8 awk9
[root@rocky9 ~]# awk -v n=0 '!n++' awk.txt
nihao awk1 awk2 awk3
结果显示:
-v n=0 在 awk 程序开始执行之前设置一个变量,并将其初始值设为 0。
n++ 是后增量操作
当 awk 开始处理第一行时,变量 n 的值为 0,因此 !n(即 !0)的值为 1
因为在逻辑上,0 被视为假,而 !0 则是真,即 1。因此,第一行会被打印出来。
当处理第二行时,由于 n++ 的操作,n 的值变为 1。此时,!n(即 !1)的值为 0(
因为在逻辑上,1 被视为真,而 !1 则是假,即 0。因此,第二行及之后的行不会被打印。
当递增与!同时存在的时候,!优先生效
在awk中可以设定数组
[root@rocky9 ~]# awk 'BEGIN{array[0]=100;print array[0]}'
100
7、awk数学运算示例
所谓的数学运算,其实就是我们平常所说的二元运算,常见的运算符号有:
+ - * / ^ %
普通数学运算
[root@rocky9 ~]# awk 'BEGIN{print 100+3 }'
103
[root@rocky9 ~]# awk 'BEGIN{print 100*3 }'
300
[root@rocky9 ~]# awk 'BEGIN{print 100/3 }'
33.3333
[root@rocky9 ~]# awk 'BEGIN{print 100%3 }'
1
BEGIN和变量运算
[root@rocky9 ~]# awk -v 'count=0' 'BEGIN{count++;print count}'
1
[root@rocky9 ~]# awk -v 'count=0' 'BEGIN{count--;print count}'
-1
在之前的案例基础上,进行统计运算每个学生的总分,每个班级的课程总分
[root@rocky9 ~]# awk 'BEGIN{printf "---------------------------
\n|%-3s|%2s|%2s|%2s|%2s|\n---------------------------\n","姓名","语文","数学","历史","总分";yu=0;shu=0;li=0;total} NR>=1 {yu=$2+yu;shu=$3+shu;li=$4+li;total=$2+$3+$4; printf "|%-3s|%4d|%4d|%4d|%4d|\n",$1,$2,$3,$4,$2+$3+$4} END{printf "---------------------------\n|%-3s|%4d|%4d|%4d|%4d|\n学生总数总: %2d\n","合计",yu,shu,li,total,NR}' course_scores.txt
---------------------------
|姓名 |语文|数学|历史|总分|
---------------------------
|张三 | 100| 56| 99| 255|
|李四 | 90| 68| 89| 247|
|王五 | 50| 78| 67| 195|
|赵六 | 80| 99| 89| 268|
---------------------------
|合计 | 320| 301| 344| 268|
学生总数总: 4
8、awk逻辑运算示例
所谓的逻辑运算,其实指的就是 与或非的操作。基本语法格式如下:
与&& - 并且关系
或|| - 或者关系
非! - 取反关系
与运算:真真为真,真假为假,假假为假
[root@rocky9 ~]# awk 'BEGIN{print 100>=2 && 100>=3 }'
1
[root@rocky9 ~]# awk 'BEGIN{print 100>=2 && 1>=100 }'
0
或运算:真真为真,真假为真,假假为假
[root@rocky9 ~]# awk 'BEGIN{print 100>=2 || 1>=100 }'
1
[root@rocky9 ~]# awk 'BEGIN{print 100>=200 || 1>=100 }'
0
注意:ubuntu24系统上,默认的awk版本是,mawk 1.3.4 20240123,有可能导致
root@ubuntu24:~# awk 'BEGIN{print 100>=2 && 100>=3 }'
awk: line 1: syntax error at or near =
解决办法:安装最新版本即可
root@ubuntu24:~# apt install gawk -y
[root@rocky9 ~]# awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
root
python
[root@rocky9 ~]# awk -F: '$3==0 || $3>=1000 {print $1,$3}' /etc/passwd
root 0
python 1000
[root@rocky9 ~]# awk -F: '$3==0 && $3>=1000 {print $1,$3}' /etc/passwd
[root@rocky9 ~]# awk -F: '!($3<1000) {print $1,$3}' /etc/passwd
python 1000
[root@rocky9 ~]# awk -F: 'NR>=1&&NR<=2{print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
非关系
[root@rocky9 ~]# awk 'BEGIN{print i}'
[root@rocky9 ~]# awk 'BEGIN{print !i}'
1
[root@rocky9 ~]# awk -v i=10 'BEGIN{print !i}'
0
[root@rocky9 ~]# awk -v i=-3 'BEGIN{print !i}'
0
[root@rocky9 ~]# awk -v i=0 'BEGIN{print !i}'
1
[root@rocky9 ~]# awk -v i=abc 'BEGIN{print !i}'
0
[root@rocky9 ~]# awk -v i='' 'BEGIN{print !i}'
1
9、awk匹配运算示例
所谓的匹配运算,主要指的是关键字无法精确性的匹配相关信息了,但是我们可以结合一些关键字信息进
行模糊的匹配。对于匹配运算来说,它有一些需要注意的事情,具体内容如下:
注意事项:
如果没有指定,为空模式,匹配每一行
如果指定”/匹配条件/”,则表示仅处理能够匹配到的内容
如果指定关系表达式,只有结果为真的情况下,才会被处理
真:结果为非0值,非空字符串,空格也是真
假:结果为空字符串或0值,数值不用加””
真假值匹配
假值匹配
[root@rocky9 ~]# awk '"" {print $1,$3}' awk.txt
[root@rocky9 ~]# awk '0 {print $1,$3}' awk.txt
非零真值匹配
[root@rocky9 ~]# awk '"aaa" {print $1,$3}' awk.txt
nihao awk2
nihao awk5
nihao awk8
[root@rocky9 ~]# awk '9 {print $1,$3}' awk.txt
nihao awk2
nihao awk5
nihao awk8
[root@rocky9 ~]# awk -v n=8 'n{print $1,$3}' awk.txt
nihao awk2
nihao awk5
nihao awk8
内容匹配
内容匹配
[root@rocky9 ~]# awk -F ':' '$1 ~ "^ro" {print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@rocky9 ~]# awk -F ':' '$1 ~ "ftp" {print $0}' /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@rocky9 ~]# awk -F ':' '$1 ~ "^[a-d].*" {print $0}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
内容不匹配
[root@rocky9 ~]# awk -F ':' '$1 !~ "^ro" {print $0}' /etc/passwd
[root@rocky9 ~]# awk -F ':' '$1 !~ "^[a-r].*" {print $0}' /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd
daemon:/dev/null:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
内容处理
准备不规则格式文件
[root@rocky9 ~]# cat zhengli.txt
http://www.sswang.org/index.html
http://www.sswang.org/1.html
http://api.sswang.org/index.html
asdfasdfsd
adfsdf
文件的规整
[root@rocky9 ~]# awk '/^[ \t]*/{print NR"--->"$1}' zhengli.txt
1--->http://www.sswang.org/index.html
2--->http://www.sswang.org/1.html
3--->http://api.sswang.org/index.html
4--->asdfasdfsd
5--->adfsdf
多值匹配打印
[root@rocky9 ~]# awk 'i=1;j=1{print $1,$3}' awk.txt
nihao awk1 awk2 awk3
nihao awk2
nihao awk4 awk5 awk6
nihao awk5
nihao awk7 awk8 awk9
nihao awk8
[root@rocky9 ~]# awk 'i=1{print $0};j=1{print $1,$3}' awk.txt
nihao awk1 awk2 awk3
nihao awk2
nihao awk4 awk5 awk6
nihao awk5
nihao awk7 awk8 awk9
nihao awk8
命令解析:
i=1;j=1{print $1,$3} 是两条命令
i=1; 虽然后面没有添加{},但是默认是 {print $0} 打印整行
假值匹配
[root@rocky9 ~]# awk '0' awk.txt
真值匹配
[root@rocky9 ~]# awk '!0' awk.txt
nihao awk1 awk2 awk3
nihao awk4 awk5 awk6
nihao awk7 awk8 awk9
10、awk内置函数示例
在awk内部预制了一些函数,借助于这些函数,我们可以实现相关场景的快速操作。这些内置函数的常见类型有:
数值类内置函数
int(expr) 截断为整数:int(123.45)和int("123abc")都返回123,int("a123")返回0
sqrt(expr) 返回平方根
rand() 返回[0,1)之间的随机数,默认使用srand(1)作为种子值
srand([expr]) 设置rand()种子值,省略参数时将取当前时间的epoch值(精确到秒的epoch)作为种子值
字符串类内置函数
sprintf(format, expression1, ...):返回格式化后的字符串
length():返回字符串字符数量、数组元素数量、或数值转换为字符串后的字符数量
strtonum(str):将字符串转换为十进制数值
如果str以0开头,则将其识别为8进制
如果str以0x或0X开头,则将其识别为16进制
tolower(str):转换为小写
toupper(str):转换为大写
index(str,substr):从str中搜索substr(子串),返回搜索到的索引位置,搜索不到则返回0
数据操作内置函数
substr(string,start[,length]):从string中截取子串
split(string, array [, fieldsep [, seps ] ]):将字符串分割后保存到数组array中
match(string,reg[,arr]):使用reg正则规则匹配string信息,默认返回匹配的索引,可以将内容存到数组
int数据取整
[root@rocky9 ~]# awk 'BEGIN{print int(123.45)}'
123
[root@rocky9 ~]# awk 'BEGIN{print int(123.565)}'
123
sqrt数据求平方根
[root@rocky9 ~]# awk 'BEGIN{print sqrt(9)}'
3
rand()求0-1的随机数
[root@rocky9 ~]# awk 'BEGIN{print rand()}'
0.237788
srand() 设定rand()的随机权重,权重固定,rand()值固定
[root@rocky9 ~]# awk 'BEGIN{srand();print rand()}'
0.858697
[root@rocky9 ~]# awk 'BEGIN{srand();print rand()}'
0.587366
[root@rocky9 ~]# awk 'BEGIN{srand(2);print rand()}'
0.610198
[root@rocky9 ~]# awk 'BEGIN{srand(2);print rand()}'
0.610198
结合srand()获取随机整
结合srand()获取随机整数
[root@rocky9 ~]# awk 'BEGIN{srand();print int(22*rand())}'
10
[root@rocky9 ~]# awk 'BEGIN{srand();print int(22*rand())}'
7
字符串实践
sprintf设定数据基本样式
[root@rocky9 ~]# awk 'BEGIN{a=sprintf("%s-%d-%s","abc",23,"ert"); print a}'
abc-23-ert
length获取字符串长度
[root@rocky9 ~]# awk 'BEGIN{v="nsfadsafdsaf";print length(v)}'
12
tolower转换为小写
[root@rocky9 ~]# awk 'BEGIN{v="ADMIN";print tolower(v)}'
admin
toupper转换为大写
[root@rocky9 ~]# awk 'BEGIN{v="nsfad";print toupper(v)}'
NSFAD
index查找子字符串的位置
[root@rocky9 ~]# awk 'BEGIN{str="nsfad";print index(str, "fa")}'
3
[root@rocky9 ~]# awk 'BEGIN{str="nsfad";print index(str, "ns")}'
1
[root@rocky9 ~]# awk 'BEGIN{str="nsfad";print index(str, "ad")}'
4
substr字符串截取
[root@rocky9 ~]# awk 'BEGIN{v="abcdefgh";print substr(v,3)}'
cdefgh
[root@rocky9 ~]# awk 'BEGIN{v="abcdefgh";print substr(v,3,3)}'
cde
split切割字符串
[root@rocky9 ~]# awk 'BEGIN{split("abc-def-gho-pq",arr,"-",seps); print
length(arr), arr[3], seps[1]}'
4 gho -
[root@rocky9 ~]# awk 'BEGIN{split("abcde",arr,"-");print arr[1]}'
abcde
[root@rocky9 ~]# echo "12:34:56" | awk '{split($0,a,":");print a[1],a[2],a[3]}'
12 34 56
match字符串匹配
[root@rocky9 ~]# awk 'BEGIN{str="safdsajfkdsajlfjdsl";print match(str,"j.*s")}'
7
[root@rocky9 ~]# awk
'BEGIN{str="safdsajfkdsajlfjdsl";match(str,"j.*s",arry);print arry[0]}'
jfkdsajlfjds
11、awk时间和匹配函数示例
awk还内置了一些关于时间和数据类型的内置函数,具体信息如下
时间类内置函数
mktime("YYYY MM DD HH mm SS [DST]"):构建一个时间,构建失败则返回-1
systime():返回当前系统时间点,返回的是秒级epoch值
strftime([format [, timestamp [, utc-flag] ] ]):将时间格式转换为字符串
数据类型相关内置函数
isarray(var):测试var是否是数组,返回1(是数组)或0(不是数组)
typeof(var):返回var的数据类型,有以下可能的值:
“array”:是一个数组
“regexp”:是一个真正表达式类型,强正则字面量才算是正则类型,如@/a.*ef/
“number”:是一个number
“string”:是一个string
“strnum”:是一个strnum,参考strnum类型
“unassigned”:曾引用过,但未赋值,例如”print f;print typeof(f)”
“untyped”:从未引用过,也从未赋值过
时间函数实践
systime返回当前系统时间点
[root@rocky9 ~]# awk 'BEGIN{print systime()}'
1655618798
mktime设置一个时间
[root@rocky9 ~]# awk 'BEGIN{print mktime("2032 4 29 11 32 19")}'
1966822339
trftime获取格式日期
[root@rocky9 ~]# awk 'BEGIN{print strftime()}'
日 6月 19 14:11:35 CST 2022
结合xargs设定时间格式
[root@rocky9 ~]# awk 'BEGIN{print mktime("2032 4 29 11 32 19") | "xargs -i date -
d@{} +\"%F %T\""}'
2032-04-29 11:32:19
# 设定时间格式
[root@rocky9 ~]# awk 'BEGIN{print strftime("%F %T %z", mktime("2032 4 29 11 32
19"))}'
2032-04-29 11:32:19 +0800
格式判断实践
isarray判断是否是一个数组
awk 'BEGIN{v="abcdefgh";print isarray(v)}'
awk 'BEGIN{v=("aa" "bb" 11);print isarray(v)}'
作者:于浩 创建时间:2024-01-15 17:13
最后编辑:于浩 更新时间:2026-07-12 22:32
最后编辑:于浩 更新时间:2026-07-12 22:32