Shell ❀ 三剑客 - Grep + Sed + Awk
文章目录
- 八、三剑客 - Grep + Sed + Awk
- 1、Grep - 过滤
- 1.1 常用grep参数
- 1.2 使用方法
- 2、Sed - 行匹配
- 2.1 执行原理
- 2.2 常见语法
- 2.3 使用方法
- 2.3.1 地址边界的设定
- 2.3.2 基础编辑命令
- 2.3.3 扩展操作
- 2.3.4 命令执行案例
- 3、Awk - 列匹配
- 3.1 awk能做什么
- 3.2 执行原理
- 3.3 命令的使用
- 3.4 语法格式与使用
- 3.4.1 输出方式
- 3.4.1.1 print的使用格式与参数
- 3.4.1.2 printf的使用格式与参数
- 3.4.1.3 重定向操作
- 3.4.2 变量操作
- 3.4.2.1 记录变量
- 3.4.2.2 数据变量
- 3.4.2.3 自定义变量
- 3.4.2.4 常见操作符号
- 3.4.2.5 常见模式
- 3.4.2.6 模式类型
- 3.4.2.7 Action类型
- 3.4.2.8 控制语句
- 3.4.2.9 数组操作
- 3.4.2.10 内置函数
八、三剑客 - Grep + Sed + Awk
1、Grep - 过滤
grep
家族分为grep
、egrep
、fgrep
,根据用户指定的过滤条件对目标文件进行逐行匹配检查,打印出符合条件的行,即文本搜索工具;
grep
:支持使用基本正则表达式;egrep
:支持使用扩展正则表达式;fgrep
:不支持使用正则表达式;
# 给grep家族加上特定颜色
[root@localhost shell]# alias | grep grep
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias xzegrep='xzegrep --color=auto'
alias xzfgrep='xzfgrep --color=auto'
alias xzgrep='xzgrep --color=auto'
alias zegrep='zegrep --color=auto'
alias zfgrep='zfgrep --color=auto'
alias zgrep='zgrep --color=auto'
# 修改系统语言为英文
[root@localhost shell]# cat /etc/locale.conf
LANG="en_US.UTF-8"
1.1 常用grep参数
-n
:显示行号;-o
:只显示匹配的内容;-q
:静默模式,没任何输出,需要用echo $?
判断是否执行成功,echo $?
返回0代表执行成功,其他非0值代表执行失败;-l
:如果匹配成功只将文件名称打印出来,常与-r
连用;-A
:如果匹配成功,则将匹配行及其后n行一起打印出来;-B
:如果匹配成功,则将匹配行及其前n行一起打印出来;-C
:如果匹配成功,则将匹配行及其前后n行一起打印出来;--color
:赋予颜色展示,默认携带参数;-c
:如果匹配成功,则将匹配的行数打印出来;-E
:等同于egrep
;-i
:忽略大小写;-v
:取反,即不匹配;-w
:完全匹配;-r
:递归匹配目录下文件内容。
1.2 使用方法
# 直接使用
[root@localhost shell]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
# 显示行号
[root@localhost shell]# grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
# 静默输出判断
[root@localhost shell]# grep -q root /etc/passwd
[root@localhost shell]# echo $?
0
# 匹配成功返回文件名称,返回为文件绝对路径
[root@localhost shell]# grep -lr root /etc/passwd
/etc/passwd
# 匹配成功向下多打印2行
[root@localhost shell]# grep -n -A 2 root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
2-bin:x:1:1:bin:/bin:/sbin/nologin
3-daemon:x:2:2:daemon:/sbin:/sbin/nologin
--
10:operator:x:11:0:operator:/root:/sbin/nologin
11-games:x:12:100:games:/usr/games:/sbin/nologin
12-ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
# 匹配忽略大小写
[root@localhost shell]# grep -i Root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
# 完全存在bin的行反向匹配(内容过多,只显示一行)
[root@localhost shell]# grep -w -v bin /etc/passwd | head -n 1
daemon:x:2:2:daemon:/sbin:/sbin/nologin
# 递归匹配(首先显示当前执行目标目录的相对路径,其次回显匹配内容)
[root@localhost shell]# cp /etc/passwd .
[root@localhost shell]# cp /etc/shadow .
[root@localhost shell]# grep -r root .
./passwd:root:x:0:0:root:/root:/bin/bash
./passwd:operator:x:11:0:operator:/root:/sbin/nologin
./shadow:root:$1$Be4wm3PK$ewirp4uOSHUMaxelB2bRG.::0:99999:7:::
# 添加-n可以增加回显行号,推荐共用
[root@localhost shell]# grep -r -n root .
./passwd:1:root:x:0:0:root:/root:/bin/bash
./passwd:10:operator:x:11:0:operator:/root:/sbin/nologin
./shadow:1:root:$1$Be4wm3PK$ewirp4uOSHUMaxelB2bRG.::0:99999:7:::
# 扩展正则匹配
[root@localhost shell]# grep -Ew "^[a-z]{4}\:{0,1}" passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
sssd:x:979:977:User for sssd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
rngd:x:975:973:Random Number Generator Daemon:/var/lib/rngd:/sbin/nologin
2、Sed - 行匹配
流编辑器stream editor
:sed
命令是将一系列的编辑命令应用与一批文本的理想工具,sed
命令拥有非交互式和高效的特点,可以为用户节省大量的时间;sed
命令是一个非交互式的文本编辑器,它可以对来自文本文件以及标准输入的文本进行编辑,其中标准输入可以是来自键盘、文件重定向、字符串、变量或者管道的文本;sed
命令会从文件或者标准输入中一次读取一行数据,将其复制到缓冲区,然后读取命令行或者脚本的编辑子命令,对缓冲区中的文本进行编辑,重复此过程直到文本处理完毕。
2.1 执行原理
模式空间pattern space
sed
在内存里开辟模式空间,处理文件的每个输入行,最多8192
字节;PATT
处理文件的内容,对输入行使用命令进行处理;
保存空间 holding space
sed
在内存里开辟保留空间,保存已经处理过的输入行,最多8192
字节;HOLD
默认有一个空行,保存已经处理过的输入行的空间,也在内存上;
命令执行原理
sed
编辑器逐行处理文件,并将结果输出打印到屏幕上;sed
命令将当前处理的行读入模式空间进行处理;sed
处理完一行将其从模式空间中删除,然后将下一行读取模式空间进行处理、显示,直至处理完最后一行;sed
在临时缓冲区对文件进行处理,所以不会修改原文件,除非显示指明-i
选项;sed
运行过程中维护这两个缓冲区,一个是活动的模式空间,另一个是起辅助作用的暂存缓冲区;
2.2 常见语法
sed OPTIONS... '[动作]' [文件名称...]
-
-n
,-quiet
:不输出模式空间中的内容,不带n会回显文件原内容,查找到的行进行双重回显; -
-i
:直接编辑原文件,默认不对原文件进行操作 -
-e
:使用多个命令进行操作 -
-f /path/from/sed_script
:从指定的文本中读取处理脚本 -
-r
:使用扩展正则表达式
2.3 使用方法
sed
的常见使用方法与参数详解;
2.3.1 地址边界的设定
-
#
:#
为数字,指需要操作处理的行 -
$
:表示最后一行,多个文件进行操作的时候,为最后一个文件的最后一行 -
/regexp/
:表示能够被regexp
匹配到的行,基于正则表达式匹配 -
/regexp/I
:不区分大小写 -
\%regexp%
:%
为边界定位符,可以用其他符号替代 -
addr1,addr2
:指定范围内的所有行 -
first~step
:指定起始位置与步长 -
addr1,+N
:指定行以及以后的N行 -
addr1,~N
:指定行以及以前的N行
操作案例
# 回显第3行
[root@localhost shell]# sed -n '3p' test.txt
# 回显第3行与第5行
[root@localhost shell]# sed -n '3p,5p' test.txt
# 回显第2至第5行
[root@localhost shell]# sed -n '2,5p' test.txt
# 回显第10行至末尾行
[root@localhost shell]# sed -n '10,$p' test.txt
# 回显数字重复3次的行
[root@localhost shell]# sed -n '/[0-9]{3}/p' test.txt
# 回显指定显示内容到另一个指定显示内容的行,aaa与bbb均需要存在,无开头无回显, 无结尾回显至末尾
[root@localhost shell]# sed -n '/aaa/,/bbb/p' test.txt
2.3.2 基础编辑命令
d
:删除匹配到的行,d
不能与参数-n
并用p
:打印模式空间中的内容a \text
:append
,在匹配到的行之后添加内容i \text
:insert
,在匹配到的行之前追加内容c \text
:replace
,在匹配到的行和给定的内容进行文本替换s /regexp/replacement/flags
:substitute
查找替换,把text
替换为regexp
匹配到的内容,/
可以用其他无特殊任意符号代替
其他编辑命令:
-
r
:读入文件内容追加到匹配行后面R
:读入文件一行内容追加到匹配行后面
常用flags
:
-
g
:global
全局替换i
:不区分大小写p
:print
成功替换则打印输出
-
y
:y/source/dest/
固定长度替换,要求替换长度相同 -
w /path/to/somefile
:将匹配到的文件另外保存到指定文件中
操作案例
# 替换每行第一个north为hello
[root@localhost shell]# sed 's/north/hello/' test.txt
[root@localhost shell]# sed 'sAnorthAhelloA' test.txt
[root@localhost shell]# sed 's#north#hello#' test.txt
# 全部替换
[root@localhost shell]# sed 's/north/hello/g' test.txt
# 替换第一行所有的north
[root@localhost shell]# sed '1 s/north/hello/g' test.txt
# 替换第一行第一个north
[root@localhost shell]# sed '1 s/north/hello/' test.txt
# 替换第一行第二个north
[root@localhost shell]# sed '1 s/north/hello/ 2' test.txt
# 删除第3行并回显(文件内容并不会删除)
[root@localhost shell]# sed '3d' test.txt
# 删除第3行至第5行
[root@localhost shell]# sed '3,5d' test.txt
# 删除某个配置文件中的空行与注释
[root@localhost shell]# sed -r '/^$|^#/d' /etc/ssh/sshd_config
# 在第3行前加入/后加入/替换第3行,命令中间空格可以自动识别,推荐加上
[root@localhost shell]# sed '3i ----------' test.txt
[root@localhost shell]# sed '3a ----------' test.txt
[root@localhost shell]# sed '3c ----------' test.txt
2.3.3 扩展操作
!
:对指定行以外的所有行应用命令=
:打印当前行号~
:表示从First
开始,以步长Step
递增&
:代表被替换的内容:
:命令并列{ }
:对单个地址或地址范围进行批量操作+
:地址范围中用到的符号,加法运算符( )
:对匹配内容进行排序并调用
操作案例
# -n 去掉默认输出,2,4p 输出第2行、第4行的内容,= 输出剩余全部行号
[root@localhost shell]# sed -n '3,4p;=' test.txt
# 3,4{p;=}输出第3行与第4行的内容与行号
[root@localhost shell]# sed -n '3,4{p;=}' test.txt
# 删除某个配置文件中的空行与注释
[root@localhost shell]# sed -nr '/^$|^#/!p' /etc/ssh/sshd_config
# \1代表第一个()内容,\2代表第二个()内容
[root@localhost shell]# echo aaaaa_bbbbb | sed -r 's/(^.*)_(.*$)/\2_\1/g'
bbbbb_aaaaa
2.3.4 命令执行案例
- 把/etc/passwd 复制到/tmp/test.txt,用sed打印所有行;
[root@localhost shell]# cp /etc/passwd ./test.txt sed -n 'p' test.txt
- 打印test.txt的3到10行;
[root@localhost shell]# sed -n '3,10p' test.txt
- 打印test.txt 中包含’root’的行;
[root@localhost shell]# sed -n '/root/p' test.txt
- 删除test.txt 的15行以及以后所有行;
[root@localhost shell]# sed -n '15,$p' test.txt
- 删除test.txt中包含’bash’的行;
[root@localhost shell]# sed -n '/bash/d' test.txt
- 替换test.txt 中’root’为’toor’;
[root@localhost shell]# sed -n 's/root/toor/gp' test.txt
- 替换test.txt中’/sbin/nologin’为’/bin/login’
[root@localhost shell]# sed -n 's@/sbin/nologin@/bin/login@g' test.txt
# 注意一点就是分隔符可以是任意不相同字符,并不仅仅是/
- 删除test.txt中5到10行中所有的数字;
[root@localhost shell]# sed -n '5,10 s/[0-9]//gp' test.txt
- 删除test.txt 中所有特殊字符(除了数字以及大小写字母);
[root@localhost shell]# sed -n 's/[^a-zA-Z0-9]//gp' test.txt
- 在test.txt 20行到末行最前面加’aaa:’
[root@localhost shell]# sed -n '20 s/$/aaa:/p' test.txt
- 删除centos7系统/etc/grub2.cfg文件中所有以空白开头的行的行首空白字符
[root@localhost shell]# sed '/^ /d' /etc/grub2.cfg
- 删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符
[root@localhost shell]# sed '/^# /d' /etc/fstab
3、Awk - 列匹配
模式扫描和文本处理语言Pattern scanning and text processing language
:awk
适合于文本处理和报表生成,awk
是一种非常强大的数据处理工具,其本身可以称为是一种程序设计语言,因而具有其他程序设计语言所共同拥有的一些特征,例如变量、函数、表达式等,通过awk
用户可以编写一些非常实用的文本处理工具;
3.1 awk能做什么
awk
是Linux以及Unix环境中现有的功能最强大的数据处理工具,简单来说,awk
是一种处理文本数据的编程语言,awk
的设计使得它非常适合于处理由行和列组成的文本数据,而在Linux或者Unix环境中,这种类型是非常普遍的;
awk
还是一种编程语言环境,它提供了正则表达式的匹配,流程控制、运算符、表达式、变量以及函数等一系列的程序设计语言所具备的特性,它从C语言中获取了一些优秀的思想,awk
程序可以读取文本文件,对数据进行排序,对其中的数值执行计算已经生成报表等;
3.2 执行原理
awk
来处理数据,在awk处理数据时,它会反复执行下面4个步骤:
- 自动从指定的数据文件中读取行文本;
- 自动更新
awk
的内置系统变量的值,例如列数变量NF
、行数变量NR
、行变量$0
以及各个列变量$1
、$2
等; - 依次执行程序中所有的匹配模式及操作;
- 当执行完程序中所有的匹配模式及其操作之后,如果数据文件中仍然还有未读取的数据行,则返回到第一步,重复执行;
3.3 命令的使用
命令执行
awk 'program-text' datafile
执行awk
脚本
awk -f program-file file
# -f : 从脚本文件program-file中读取awk脚本,file为执行脚本目标文件
可执行的脚本文件
#!/bin/awk -f
awk-script file
# awk-script为awk脚本文件名称,file为执行脚本目标文件
3.4 语法格式与使用
awk [options] 'script' file1 file2 ...
# awk [选项] '脚本' 目标文件路径
awk [options] 'PATTERN {action}' file1 file2 ...
# awk [选项] '条件{动作}' 目标文件路径
3.4.1 输出方式
常见的输出类型主要有:print
、变量输出、操作符、布尔值、模式结构、控制语句;
3.4.1.1 print的使用格式与参数
print item1,item2,...
- 各项目之间使用逗号隔开,而输出时则以空白字符分隔;
- 输出的
item
可以为字符串或数值、当前记录的字段、变量或awk
表达式,数值会先转换为字符串,而后输出 print
命令后面的item
可以省略,此时其功能相当于print $0
,若想输出空白行,需要使用print " "
# print示范案例
[root@localhost shell]# awk 'BEGIN{ print "line one\nline two\nline three" }'
line one
line two
line three
[root@localhost shell]# awk -F: '{print $1,$2,$3}' test.txt
root x 0
bin x 1
daemon x 2
# 获取网卡IP地址
[root@localhost ~]# ifconfig br0 | awk 'NR==2{print $2}'
10.81.20.166
[root@localhost ~]# ifconfig br0 | grep 10.81.20.166 | tr -s " " | cut -d " " -f 3
10.81.20.166
3.4.1.2 printf的使用格式与参数
- 其与
print
命令的不同是,printf
需要指定format
; format
用于指定后面的每个item
的输出格式;printf
语句不会自动打印换行符\n
;
format
格式的指示符如下:
%c
:显示字符的ASCII码%d
,%i
:十进制整数%e
,%E
:科学计数法显示数值%f
:显示浮点数%g
,%G
:以科学计数法的格式或浮点数的格式显示数值%s
:显示字符串%u
:无符号整数%%
:显示%本身
常用修饰符:
N
:显示宽度-
:左对齐+
:显示数值符号
操作案例
[root@localhost shell]# awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd | head -n 3
root 0
bin 1
daemon 2
[root@localhost shell]# awk -F: '{print $1"\t\t\t"$NF}' /etc/passwd | column -t
# column -t 根据输入行数进行制表
[root@localhost shell]# awk -F: 'BEGIN{print "name\tuid\tgid\tshell"}{print $1"\t"$3"\t"$4"\t"$7}' test.txt
name uid gid shell
root 0 0 /bin/bash
bin 1 1 /sbin/nologin
daemon 2 2 /sbin/nologin
adm 3 4 /sbin/nologin
lp 4 7 /sbin/nologin
3.4.1.3 重定向操作
print items > output-file # 重定向
print items >> output-file # 追加重定向
print items | output-file
特殊文件描述符:
/dev/stdin
:标准输入/dev/stdout
:标准输出/dev/stderr
:错误输出/dev/fd/N
:某特定文件描述符
[root@localhost shell]# awk -F: '{printf "%-15s %i\n",$1,$3 > "test1"}' /etc/passwd
3.4.2 变量操作
3.4.2.1 记录变量
FS
:field separator
:读取文本时,所使用字段分隔符;OFS
:output field separator
:输出分隔符;OFS="x"
:指定输出分隔符
awk -F[分隔符,默认为空格] 'BEGIN{判断条件前执行的命令}判断条件{执行命令}END{判断条件后执行的命令}' 文件路径
# awk -F : F指定输入分隔符,等于-v FS=:(-v FS与-vFS均可识别),默认支持扩展正则
操作案例
[root@localhost shell]# awk -F: '{print $1,$NF}' test.txt | column -t
root /bin/bash
[root@localhost shell]# awk -vFS=: '{print $1,$NF}' test.txt
root /bin/bash
[root@localhost shell]# ifconfig br0 | awk 'NR==2{print $2}'
10.81.20.166
# “+”为扩展正则表达式,代表出现一次或多次
[root@localhost shell]# ifconfig br0 | awk -F"[ ]+" 'NR==2{print $3}'
10.81.20.166
# 由于未匹配到多个空格,因此IP地址的位置,参考第一个匹配内容是单个空格还是多个空格
[root@localhost shell]# ifconfig br0 | awk 'NR==2'
inet 10.81.20.166 netmask 255.255.255.0 broadcast 10.81.20.255
[root@localhost shell]# awk -F: -vOFS=: '{print $1,$NF}' test.txt
root:/bin/bash
[root@localhost shell]# awk -F: 'BEGIN{OFS=":"}{print $1,$NF}' test.txt
root:/bin/bash
3.4.2.2 数据变量
NR
:awk
命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;NF
:当前记录的字段个数,默认以空格为间隔符,可以使用$NF
代表最后一列;FNR
:用于记录正处理的行是当前这一文件中被总共处理的行数;awk
处理多个文件,各自文件计数;ENVIRON
:当前shell环境变量及其值得关系数组;
操作案例
# 输出第2行有几列
[root@localhost shell]# awk -F: 'NR==2{print NF}' test.txt
7
# 输出共有几行
[root@localhost shell]# awk '{print NR}' test.txt
1
2
# 输出第2行最后一列内容
[root@localhost shell]# awk -F: 'NR==2{print $NF}' test.txt
/sbin/nologin
3.4.2.3 自定义变量
awk
允许用户自定义变量,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头,awk
变量名称区分字符大小写;
# 在awk中给变量赋值使用赋值语句进行赋值
[root@localhost shell]# awk 'BEGIN{test="hello";print test}'
hello
# 在awk中使用赋值变量
[root@localhost shell]# awk -v test="hello" 'BEGIN {print test}'
hello
3.4.2.4 常见操作符号
操作符号与Linux系统基本完全一致,一致则不做重复赘述,不一致提供相关解释。
算术运算符
-x
:负值+x
:转换为数值x^y
:次方x**y
:次方x*y
:乘法x/y
:除法x+y
:加法x-y
:减法x%y
:取余
字符串操作符
[root@localhost shell]# awk 'BEGIN {print "This","is","test","!"}'
This is test !
赋值操作符
=
:如果符号为=
号,使用/=/
会有语法错误,因此使用/[=]/
代替;+=
:其余同普通运算完全一致;-=
*=
/=
%=
^=
**=
++
- `–`
布尔值
awk
中任何非0或非空字符串都为真,反之则为假;
比较操作符
<
<=
>
>=
==
!=
~
:匹配,在正则表达式中^与$分别代表行开头与结束,在awk
中代表列开头与结束!~
:不匹配,注意点同上
逻辑关系符
&&
:与||
:或!
:非
条件表达式
if
elif
else
fi
3.4.2.5 常见模式
awk 'program' input-file1 input-file2 ...
#其中program为“
#pattern { action }
#pattern { action }
#...
3.4.2.6 模式类型
Regexp
:正则表达式,格式为/regular expression/
Expression
:表达式,其值非0或非空白字符时满足条件,Ranges
:指定匹配范围,格式为pat1,pat2
BEGIN/END
:特殊模式,仅在awk
命令执行前/后运行一次Empty
:匹配任意输入行
3.4.2.7 Action类型
-
Expressions
-
Control statements
-
Compound statements
-
Input statements
-
Output statements
-
/正则表达式/
:使用通配符的扩展集
+
匹配其前的单个字符一次以上,是awk
自有的元字符,不适用于grep
或sed
等;
?
匹配其前的单个字符一次或0次,是awk
自有的元字符,不适用于grep
或sed
等; -
关系表达式:可以用下面的运算符表中的关系运算符进行操作,可以是字符串或数字的比较;
-
模式匹配表达式:指定一个行的范围,该语法不能包括
BEGIN
与END
模式; -
BEGIN
:用户指定在第一条输入记录被处理之前所发生的动作,通常在此设定全局变量; -
END
:用户在最后一条输入记录被读取之后发生的动作;
操作案例
# 使用正则表达式匹配
[root@localhost shell]# awk -F: '/^r/ {print $1}' /etc/passwd
root
rtkit
rpc
radvd
rpcuser
rngd
# 使用BEGIN
[root@localhost shell]# awk -F: 'BEGIN {printf "%-15s %-3s %-15s\n","user","uid","shell"} $3==0,$7~"nologin" {printf "%-15s %-3s %-15s\n",$1,$3,$7}' /etc/passwd
user uid shell
root 0 /bin/bash
bin 1 /sbin/nologin
# 使用END
[root@localhost shell]# awk -F: 'BEGIN {printf "%-15s %-3s %-15s\n","user","uid","shell"} $3==0,$7~"nologin" {printf "%-15s %-3s %-15s\n",$1,$3,$7} END {print "-----End file-----"}' /etc/passwd
user uid shell
root 0 /bin/bash
bin 1 /sbin/nologin
-----End file-----
3.4.2.8 控制语句
if-else
语句格式:
if (表达式) {语句1} else if (表达式) {语句2} else {语句3}
操作案例:
[root@localhost shell]# awk -F: '{if ($1=="root") printf "%-10s %-15s\n", $1, "Admin"; else printf "%-10s %-15s\n",$1, "Common User"}' /etc/passwd | head -n 3
root Admin
bin Common User
daemon Common User
- while语句格式:
while (表达式) {语句}
操作案例:
[root@localhost shell]# awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd
[root@localhost shell]# awk -F: '{i=1;while (i<=NF) {if (length($i)>=4) {print $i};i++}}' /etc/passwd
do-while
语句格式:
do {语句} while (条件)
操作案例:
[root@localhost shell]# awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd | head -n 3
root
x
0
#计算1-100的和
[root@localhost shell]# awk 'BEGIN{do{sum+=i;i++;}while(i<=100)print "sum =",sum}'
sum = 5050
for
语句格式:
for(变量;条件;表达式){语句}
for(变量 in 数组){语句}
操作案例:
[root@localhost shell]# awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd
[root@localhost shell]# awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd
#将/etc/passwd文件内容中的最后一行内容进行统计并制表
[root@localhost shell]# awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){print A,BASH[A]}}' /etc/passwd | column -t
/bin/sync 1
/bin/bash 2
/sbin/nologin 43
/sbin/halt 1
/sbin/shutdown 1
[root@localhost shell]# awk 'BEGIN{a[0]="aaa";a[1]="bbb";a[2]=111;a[3]=222;for(i in a) print a[i]}'
case
语句格式:
switch (expression) { case VALUE or /REGEXP/: statement1,statement2,... default: statement1, ...}
break
与continue
语句格式:
常用于循环或case
语句中
next
语句格式:
[root@localhost shell]# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd |head -n 3
bin 1
adm 3
sync 5
3.4.2.9 数组操作
- 创建数组
array[index-expression]
index-expression
可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk
会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array
的方式。
要遍历数组中的每一个元素,需要使用如下的特殊结构:
for (i in array) print array[i]
# i在awk中值为数组array中的下标,若想获取下标所对应的值,选用array[i]即可
[root@localhost shell]# awk 'BEGIN{a[0]="aaa";a[1]="bbb";a[2]=111;a[3]=222;for(i in a) print a[i]}'
aaa
bbb
111
222
# 统计某个日志文件内固定时间段访问IP数量
[root@localhost shell]# awk -F"[ ]" '/22:21/,/22:26/{print $1}' access.log-20211020 | awk '{IP[$1]++}END{for (i in IP) print i,IP[i]}' | column -t
192.168.28.143 16
[root@localhost shell]# netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
LISTEN 10
ESTABLISHED 1
# 每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引
- 删除数组
delete array[index]
3.4.2.10 内置函数
- split(string, array [, fieldsep [, seps ] ])
将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列;
[root@localhost shell]# date +%T | awk '{split($0,a,":");print a[1],a[2],a[3]}'
- length([string])
返回string字符串中字符的个数;
[root@localhost shell]# awk 'BEGIN{print length("uplooking")}'
9
- substr(string, start [, length])
取string字符串中的子串,从start开始,取length个;start从1开始计数;
[root@localhost shell]# awk 'BEGIN{print substr("uplooking",u,2)}'
up
- system(command)
执行系统command并将结果返回至awk命令
[root@localhost shell]# awk 'BEGIN{print system("whoami")}'
- systime()
取系统当前时间
[root@localhost shell]# awk 'BEGIN{print systime()}'
- tolower(s)
将s中的所有字母转为小写
[root@localhost shell]# awk 'BEGIN{print tolower("WWW.baidu.COM")}'
- toupper(s)
将s中的所有字母转为大写
[root@localhost shell]# awk 'BEGIN{print toupper("WWW.baidu.COM")}'