Shell ❀ 三剑客 - Grep + Sed + Awk

Posted 无糖可乐没有灵魂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell ❀ 三剑客 - Grep + Sed + Awk相关的知识,希望对你有一定的参考价值。

文章目录

八、三剑客 - Grep + Sed + Awk

1、Grep - 过滤

grep家族分为grepegrepfgrep,根据用户指定的过滤条件对目标文件进行逐行匹配检查,打印出符合条件的行,即文本搜索工具;

  • 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 editorsed命令是将一系列的编辑命令应用与一批文本的理想工具,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 \\textappend,在匹配到的行之后添加内容
  • i \\text insert,在匹配到的行之前追加内容
  • c \\textreplace,在匹配到的行和给定的内容进行文本替换
  • s /regexp/replacement/flags substitute 查找替换,把text替换为regexp匹配到的内容,/可以用其他无特殊任意符号代替

其他编辑命令:

    • r :读入文件内容追加到匹配行后面
    • R :读入文件一行内容追加到匹配行后面

常用flags

    • gglobal 全局替换
    • i :不区分大小写
    • pprint成功替换则打印输出
  • yy/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,4p;=输出第3行与第4行的内容与行号
[root@localhost shell]# sed -n '3,4p;=' 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 languageawk适合于文本处理和报表生成,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==2print $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: 'BEGINprint "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 记录变量
  • FSfield separator:读取文本时,所使用字段分隔符;
  • OFSoutput 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==2print $2'
10.81.20.166
# “+”为扩展正则表达式,代表出现一次或多次
[root@localhost shell]# ifconfig br0 | awk -F"[ ]+" 'NR==2print $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: 'BEGINOFS=":"print $1,$NF' test.txt
root:/bin/bash
3.4.2.2 数据变量
  • NRawk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;
  • NF:当前记录的字段个数,默认以空格为间隔符,可以使用$NF代表最后一列;
  • FNR:用于记录正处理的行是当前这一文件中被总共处理的行数;awk处理多个文件,各自文件计数;
  • ENVIRON:当前shell环境变量及其值得关系数组;

操作案例

# 输出第2行有几列
[root@localhost shell]# awk -F: 'NR==2print NF' test.txt 
7
# 输出共有几行
[root@localhost shell]# awk 'print NR' test.txt
1
2
# 输出第2行最后一列内容
[root@localhost shell]# awk -F: 'NR==2print $NF' test.txt
/sbin/nologin
3.4.2.3 自定义变量

awk允许用户自定义变量,变量名命名规则与大多数编程语言相同,只能使用字母、数字和下划线,且不能以数字开头,awk变量名称区分字符大小写;

# 在awk中给变量赋值使用赋值语句进行赋值
[root@localhost shell]# awk 'BEGINtest="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自有的元字符,不适用于grepsed等;

    ? 匹配其前的单个字符一次或0次,是awk自有的元字符,不适用于grepsed等;

  • 关系表达式:可以用下面的运算符表中的关系运算符进行操作,可以是字符串或数字的比较;

  • 模式匹配表达式:指定一个行的范围,该语法不能包括BEGINEND模式;

  • 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 'BEGINdosum+=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]++ENDfor(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 'BEGINa[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, ...
  • breakcontinue语句格式:

常用于循环或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 'BEGINa[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]++ENDfor (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 'BEGINprint length("uplooking")'
9
  • substr(string, start [, length])

取string字符串中的子串,从start开始,取length个;start从1开始计数;

[root@localhost shell]# awk 'BEGINprint substr("uplooking",u,2)'
up
  • system(command)

执行系统command并将结果返回至awk命令

[root@localhost shell]# awk 'BEGINprint system("whoami")'
  • systime()

取系统当前时间

[root@localhost shell]# awk 'BEGINprint systime()'
  • tolower(s)

将s中的所有字母转为小写

[root@localhost shell]# awk 'BEGINprint tolower("WWW.baidu.COM")'
  • toupper(s)

将s中的所有字母转为大写

[root@localhost shell]# awk 'BEGINprint toupper("WWW.baidu.COM")'

以上是关于Shell ❀ 三剑客 - Grep + Sed + Awk的主要内容,如果未能解决你的问题,请参考以下文章

Shell ❀ 三剑客 - Grep + Sed + Awk

Shell文本处理工具(Linux三剑客 grep sed awk )

shell 编程四剑客简介 find sed grep awk(微信公众号摘抄)

Shell Sed命令

linux shell提取字符串,awk? grep? sed?

三剑客之sed,awk,grep,egrep