预定义变量分为两类:控制awk工作的变量和携带信息的变量。
第一类:控制AWK工作的预定义变量
RS :输入记录分隔符,默认为换行符\n ,参考RS
IGNORECASE :默认值为0,表示所有的正则匹配不忽略大小写。设置为非0值(例如1),之后的匹配将忽略
大小写。例如在BEGIN块中将其设置为1,将使FS、RS都以忽略大小写的方式分隔字段或分隔record
FS :读取记录后,划分为字段的字段分隔符。参考FS
FIELDWIDTHS :以指定宽度切割字段而非按照FS。参考FIELDWIDTHS
FPAT :以正则匹配匹配到的结果作为字段,而非按照FS划分。参考FPAT
OFS :print命令输出各字段列表时的输出字段分隔符,默认为空格" "
ORS :print命令输出数据时在尾部自动添加的记录分隔符,默认为换行符\n
CONVFMT :在awk中数值隐式转换为字符串时,将根据CONVFMT的格式按照sprintf()的方式自动转换为字
符串。默认值为"%.6g
OFMT :在print中,数值会根据OFMT的格式按照sprintf()的方式自动转换为字符串。默认值为"%.6g
第二类:携带信息的预定义变量
ARGC 和ARGV :awk命令行参数的数量、命令参数的数组。参考ARGC和ARGV
ARGIND :awk当前正在处理的文件在ARGV中的索引位置。所以,如果awk正在处理命令行参数中的某文件,
则ARGV[ARGIND] == FILENAME 为真
FILENAME :awk当前正在处理的文件(命令行中指定的文件),所以在BEGIN中该变量值为空
ENVIRON :保存了Shell的环境变量的数组。例如ENVIRON["HOME"] 将返回当前用户的家目录
NR :当前已读总记录数,多个文件从不会重置为0,所以它是一直叠加的
可以直接修改NR,下次读取记录时将在此修改值上自增
FNR :当前正在读取文件的第几条记录,每次打开新文件会重置为0
可以直接修改FNR,下次读取记录时将在此修改值上自增
NF :当前记录的字段数,参考NF
RT :在读取记录时真正的记录分隔符,参考RT
RLENGTH :match()函数正则匹配成功时,所匹配到的字符串长度,如果匹配失败,该变量值为-1
RSTART :match()函数匹配成功时,其首字符的索引位置,如果匹配失败,该变量值为0
SUBSEP : arr[x,y] 中下标分隔符构建成索引时对应的字符,默认值为\034 ,是一个不太可能出现在字符串中的不可打印字符。参考复杂数组
选项
-e program-text
--source program-text
指定awk程序表达式,可结合-f选项同时使用
在使用了-f选项后,如果不使用-e,awk program是不会执行的,它会被当作ARGV的一个参数
-f program-file
--file program-file
从文件中读取awk源代码来执行,可指定多个-f选项
-F fs
--field-separator fs
指定输入字段分隔符(FS预定义变量也可设置)
-n
--non-decimal-data
识别文件输入中的8进制数(0开头)和16进制数(0x开头)
echo '030' | awk -n '{print $1+0}'
-o [filename]
格式化awk代码。
不指定filename时,则默认保存到awkprof.out
指定为`-`时,表示输出到标准输出
-v var=val
--assign var=val
在BEGIN之前,声明并赋值变量var,变量可在BEGIN中使用
1,按字符数量读取:每一次可以读取一个字符,或者多个字符,直到把整个文件读取完
while read -n 1 char;do echo $char;done < a.txt
2,按照分隔符进行读取:一直读取直到遇到分隔符才停止,下次继续从分隔的位置处向后读取,直到读完整个文件
while read -d "m" chars;do echo "$chars";done < a.txt
3,按行读取:每次读取一行,直到把整个文件读完
是按照分隔符读取的一种特殊情况:将分隔符指定为了换行符\n
while read line;do echo "$line";done < a.txt
4,一次性读取整个文件
是按字符数量读取的特殊情况,也是按分隔符读取的特殊情况
read -N 10000000 data < a.txt
read -d '_' data < a.txt
5,按字节数量读取
awk 'awk_program' a.txt
1)a.txt是awk要读取的文件,可以是0个文件或一个文件,也可以多个文件
如果不给定任何文件,但又需要读取文件,则表示从标准输入中读取
2)单引号包围的是awk代码,也称为awk程序
尽量使用单引号,因为在awk中经常使用$
符号,而$ 符号在shell是变量符号,如果使用双引号包围awk代码,则 符 号 会 被 s h e l l 解 析 成 s h e l l 变 量 , 然 后 进 行 s h e l l 变 量 替 换 。 使 用 单 引 号 包 围 a w k 代 码 , 则 符号会被shell解析成shell变量,然后进行shell变量替换。使用单引号包围awk代码,则 符号会被shell解析成shell变量,然后进行shell变量替换。使用单引号包围awk代码,则 会脱离shell的魔掌,使得$ 符号留给了awk去解析
3)awk程序中,大量使用大括号,大括号表示代码块,代码块中间可以之间连用,代码内部的多个语句需使用分号“;” 分隔。
awk '{print $0}' a.txt
awk '{print $0}{print $0;print $0}' a.txt
awk 'BEGIN{print "我在前面"}{print $0}' a.txt
awk 'END{print "我在后面"}{print $0}' a.txt
awk 'BEGIN{print "我在前面"}{print $0}END{print "我在后面"}' a.txt
BEGIN代码块:
在读取文件之前执行,且执行一次
在BEGIN代码块中,无法使用$0或其他一些特殊变量
END代码块:
在读取文件完成之后执行,且执行一次
有END代码块,必有要读取的数据(可以是标准输入)
END代码块中可以使用$0等一些特殊变量,只不过这些特殊变量保存的是最后一轮awk循环的数据
main代码块:
读取文件时循环执行,(默认情况)每读取一行,就执行一次main代码块
main代码块可有多个
在shell命令行当中,双短横线–表示选项到此结束,后面的都是命令的参数
awk [ -- ] program-text file ...
awk -f program-file [ -- ] file ...
awk -e program-text [ -- ] file ...
cmd -x -r root -ppassword a.txt b.txt c.txt
1,选项分为长选项和短选项
2,选项分为3种:
1)不带参数的选项
2)是带参数的选项,如果该选项后面没有给参数,则报错
3)参数可选的选项,选项后面可以跟参数,也可以不跟参数
参数可选选项,如果要接参数,则必须将参数紧紧跟在选项后面,不能使用空格分隔选项和参数
3,两种参数:
1)选项型参数
2)非选项型参数
范例:awk的语法充斥着pattern{action}的模式,它们称为awk rule:awk语句块可划分如下
awk 'BEGIN{n=3} /^[0-9]/$1>5{$1=333;print $1} /Alice/{print "Alice"} END{print "hello"}' a.txt
1)pattern部分用于测试筛选数据,action表示在测试通过后执行的操作
2)pattern和action都可以省略
省略pattern,等价于对每个一行数据都执行action
awk '{print $0}' a.txt
省略代码块{action},等价于{print}即输出所有行
awk '/Alice/' a.txt 等价于 awk '/Alice/{print $0}' a.txt
省略代码块中的action,表示对筛选的行什么都不做
awk '/Alice/{}' a.txt
parttern{action}任何一部分都可以省略
awk '' a.txt
多个pattern{action}可以直接连接连用
action中多个语句连用需使用分号分隔
对于pattern{action}语句结构(都称之为语句块),其中的pattern部分可以使用下面列出的模式
# 特殊pattern
BEGIN
END
# 布尔代码块
/regulat expression/ # 正则匹配成功与否/a.*ef/{action}
relational expression # 即等值比较,大小比较 3>2{action}
pattern && pattern # 逻辑与3>2 && 3>1 {action}
pattern || pattern # 逻辑或 3>2 || 3<1 {action}
! pattern # 逻辑取反 !/a.*ef/{action}
(pattern) # 改变优先级
pattern ? pattern : pattern # 三目运算符决定的布尔值
# 范围pattern,非布尔代码块
pattern1,pattern2 # 范围,pat1打开,pat2关闭,即flip,flop模式
action部分,可以是任何语句,例如print语句。
awk读取输入文件时,每次读取一条记录(record)(默认情况下按行读取,所以此时记录就是行)。每读取一条记录,将其保存到 $0中,然后执行一次main代码段
awk '{print $0}' a.txt
如果是空文件,则因为无法读取到任何一条记录,将导致直接关闭文件,而不会进入main代码段。
touch x.log # 创建一个空文件
awk '{print "holle word"}' x.log
可设置表示输入记录分隔符的预定义变量RS(Record Separator)来改变每次读取的记录模式。
# RS="\n" , RS="m"
awk 'BEGIN{RS="\n"}{print $0}' a.txt
awk 'BEGIN{RS="m"}{print $0}' a.txt
RS通常设置在BEGIN代码块中,因为要先于读取文件就确定好RS分隔符
RS指定输入记录分隔符时,所读取的记录中是不包含分隔符字符的。例如RS="a",则$0 中一定不可能出现字符a。
RS两种可能情况:
RS为单个字符:直接使用该字符来分割记录
RS为多个字符:将其当做正则表达式,只要匹配正则表达式的符号,都用来分割记录
设置预定义变量IGNORECASE为非零值,正则匹配时表示忽略大小写
兼容模式下,只有首字符才生效,不会使用正则模式去分割记录
特殊的RS值用来解决特殊读取需求:
RS="":按段落读取
RS="\0":一次性读取所有数据,但有些特殊文件中包含了空字符\0
RS="^$":真正的一次性读取所有数据,因为非空文件不可能匹配成功
RS="\n+":按行读取,但忽略所有空行
按段落读取:RS=''
awk 'BEGIN{RS=''}{print $0"------""}' a.txt
#一次性读取所有数据:RS='\0' RS="^$"
awk 'BEGIN{RS='\0'}{print $0"------""}' a.txt
awk 'BEGIN{RS='^$'}{print $0"------"}' a.txt
# 忽略空行:RS='\n+'
awk 'BEGIN{RS='\n+'}{print $0"------""}' a.txt
# 忽略大小写:预定义变量IGNORECASE设置为非0值
awk 'BEGIN{IGNORECASE=1}{print $0"------"}' RS='[ab]' a.txt
预定义变量RT:
在awk每次读完一条记录时,会设置一个称为RT的预定义变量,表示Record Termination。
当RS为单个字符时,RT的值和RS的值是相同的。
当RS为多个字符(正则表达式)时,则RT设置为正则匹配到记录分隔符之后,真正用于划分记录时的字符。
当无法匹配到记录分隔符时,RT设置为控制空字符串(即默认的初始值)。
awk 'BEGIN{RS="(fe)?male"}{print RT}' a.txt
在读取每条记录之后,将其赋值给$0,同时还会设置NR,FNR,RT。
NR:所有文件的行号计数器
FNR:是各个文件的行号计数器
awk '{print NR}' a.txt b.txt
awk '{print FNR}' a.txt b.txt
awk读取每一条记录之后,会将其赋值给$0,同时还会对这条记录按照预定义变量 FS划分字段,将划分好的各个字段分别赋值给$1,$2, 3... 3... 3...n,同时将划分的字段数量赋值给预定义变量NF
$N 引用字段:
N=0:即$0,引用记录本身
0NF:表示引用不存在的字段,返回空字符串
N<0:报错
可使用变量或计算的方式指定要获取的字段序号。
awk '{n = 5;print $n}' a.txt
awk '{print $(2+2)}' a.txt # 括号必不可少,用于改变优先级
awk '{print $(NF-3)}' a.txt
读取record之后,将使用预定义变量 FS,FILEDWIDTHHS或FPAT中的一种来分割字段。分割完成之后,再进入main代码段(所以,在main中设置FS对本次已经读取的record是没有影响的,但会影响下次读取)
FS或 -F
FS 或者 -F:字段分隔符
Fs为单个字符时,该字符即为字段分隔符
FS为多个字符时,则采用正则表达式模式作为字段分隔符
特殊的,也是FS默认的情况,FS为单个空格时,将以连续的空白(空格,制表符,换行符)作为字段分隔符
特殊的,FS为空字符串""时,将对每个字符都进行分隔,即每个字符都作为一个字段
设置预定义变量IGNORECASE为非零值,正则匹配时表示忽略大小写(只影响正则,所以FS为单字时无影响)
如果record中无法找到FS指定的分隔符(例如将FS设置为"\n"),则整个记录作为一个字段,即$1 和$0 相等。
范例:
面试题:取出分区利用率
[20:41:33 root@Bj-Ubuntu ~]# df | awk '{print $1,$5}'
Filesystem Use%
udev 0%
tmpfs 6%
/dev/sda2 14%
tmpfs 0%
tmpfs 0%
tmpfs 0%
/dev/loop0 100%
/dev/loop1 100%
/dev/sda3 1%
tmpfs 0%
[20:42:06 root@Bj-Ubuntu ~]# df | awk -F"[[:space:]]+|%" '{print $5}'
Use
0
6
14
0
0
0
100
100
1
0
[root@longwang ~]# df | awk -F"[ %]+" '{print $5}'
Use
0
0
10
0
10
1
16
0
[root@longwang ~]# df | awk -F"[ %]+" '{print $1,$5}'
Filesystem Use
devtmpfs 0
tmpfs 0
tmpfs 10
tmpfs 0
/dev/mapper/cl-root 10
/dev/mapper/cl-data 1
/dev/sda1 16
tmpfs 0
范例
[root@VM_0_10_centos ~]# awk -F'[[ ]' '{print $1,$5}'
/apps/nginx/logs/nginx.access.log | head -n3
58.87.87.99 09/Jun/2020:03:42:43
128.14.209.154 09/Jun/2020:03:42:43
64.90.40.100 09/Jun/2020:03:43:11
取ip地址centos6
[06:47:47 root@centos6 ~]# ip a |awk -F"[ /]+" '/inet / && !/127/{print $3}'
172.31.0.10
ubuntu
[20:43:38 root@Bj-Ubuntu ~]# ip a |awk -F"[ /]+" '/inet / && !/127/{print $3}'
172.31.0.19
centos8
[root@longwang ~]# ip a | awk -F"[ /]+" '/inet / && !/127/{print $3}'
172.31.0.38
面试题:文件host_list.log 如下格式,请提取”.magedu.com”前面的主机名部分并写入到回到该文件中
[root@longwang ~]# cat host_list.log
1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
[root@longwang ~]# awk -F"[ .]" '{print $2}' host_list.log
www
blog
study
linux
python
[root@longwang ~]# awk -F"[ .]" '{print $2}' host_list.log >> host_list.log
[root@longwang ~]# cat host_list.log
1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
www
blog
study
linux
python
FS:输入字段分隔符,默认为空白字符,功能相当于 -F
范例
[root@longwang ~]# awk -v FS=':' '{print $1,FS,$3}' /etc/passwd
root : 0
bin : 1
daemon : 2
adm : 3
[root@longwang ~]# awk -v FS=":" '{print $1FS$3}' /etc/passwd
root:0
bin:1
daemon:2
[root@longwang ~]# awk -F: '{print $1,$3,$7}' /etc/passwd
root 0 /bin/bash
bin 1 /sbin/nologin
daemon 2 /sbin/nologin
[root@longwang ~]# S=;awk -v FS=$S '{print $1FS$3}' /etc/passwd
ro
bn
de
am
[root@longwang ~]# awk -v FS=":" '{print $1FS$3}' /etc/passwd | head -n3
root:0
bin:1
daemon:2
[root@longwang ~]# S=:;awk -F$S '{print $1,$3}' /etc/passwd | head -n3
root 0
bin 1
daemon 2
#-F 和 FS变量功能一样,同时使用会冲突
[root@longwang ~]# awk -v FS=":" -F";" '{print $1FS$3}' /etc/passwd | head -n3
root:x:0:0:root:/root:/bin/bash;
bin:x:1:1:bin:/bin:/sbin/nologin;
daemon:x:2:2:daemon:/sbin:/sbin/nologin;
[root@longwang ~]# awk -F";" -v FS=":" '{print $1FS$3}' /etc/passwd | head -n3
root:0
bin:1
daemon:2
#-F 和 FS变量功能一样,同时使用会 -F 优先级高
[root@longwang ~]# awk -v FS=":" -F";" '{print $1}' /etc/passwd | head -n3
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@longwang ~]# awk -v FS=";" -F":" '{print $1}' /etc/passwd | head -n3
root
bin
daemon
OFS:输出字段分隔符,默认为空白字符
[root@longwang ~]# awk -v FS=':' '{print $1,$3,$7}' /etc/passwd | head -n1
root 0 /bin/bash
[root@longwang ~]# awk -v FS=":" -v OFS=':' '{print $1,$3,$7}' /etc/passwd | head -n1
root:0:/bin/bash
RS:输入记录record分隔符,指定输入时的换行符
[root@longwang ~]# awk -v RS=' ' '{print }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP
User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel
Overflow
ORS:输出记录分隔符,输出时用指定符号代替换行符
[root@longwang ~]# awk -v RS=' ' -v ORS='###' '{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
NF:字段数量
#引用变量时,变量前不需加$
[root@longwang ~]# awk -F: '{print NF}' /etc/passwd
7
7
[root@longwang ~]# awk -F: '{print $(NF-1)}' /etc/passwd
/root
/bin
/sbin
面试题:接数最多的前3个IP
172.20.65.65 - - [24/May/2018:10:13:20 +0800] "GET /centos/6/Packages/python-iwlib-0.1-1.2.el6.x86_64.rpm HTTP/1.1" 200 14724 "-" "CentOS (anaconda)/6.9"
172.20.65.65 - - [24/May/2018:10:13:20 +0800] "GET /centos/6/Packages/hplip-common-3.14.6-4.el6.1.x86_64.rpm HTTP/1.1" 200 81384 "-" "CentOS (anaconda)/6.9"
172.20.65.65 - - [24/May/2018:10:13:20 +0800] "GET /centos/6/Packages/sane-backends-libs-gphoto2-1.0.21-5.el6.x86_64.^C
[root@longwang ~]# awk -F" +|:" '{print $1}' access_log | sort | uniq -c | sort -nr | head -n3
4870 172.20.116.228
3429 172.20.116.208
2834 172.20.0.222
[root@iZwz98 ~]# ss -tn
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 52 172.18.106.169:8222 114.246.99.151:51006
ESTAB 0 0 172.18.106.169:44128 100.100.30.26:80
ESTAB 0 0 172.18.106.169:8222 118.126.89.216:50034
[root@iZwz98 ~]# ss -tn | grep "^ESTAB" | awk -F"[[:space:]]+|:" '{print $(NF-2)}'
114.246.99.151
100.100.30.26
[root@iZwz98 ~]# ss -tn | awk -F"[[:space:]]+|:" '/^ESTAB/{print $(NF-2)}'
114.246.99.151
100.100.30.26
58.33.35.82
范例:每十分钟检查将连接数超过100个以上的IP放入黑名单拒绝访问
[root@iZwz98 ~]# vim deny_dos.sh
#!/bin/bash
LINK=100
while true;do
ss -tn | awk -F"[[:space:]]+|:" '/^ESTAB/{print $(NF-2)}' |sort | uniq -c | while read count ip ;do
if [ $count -gt $LINK ];then
iptables -A INPUT -s $ip -j REJECT
fi
done
done
[root@iZwz98 ~]# chmod +x deny_dos.sh
[root@iZwz98 ~]# crontab -e
[root@iZwz98 ~]# crontab -l
*/10 * * * * /root/deny_dos.sh
NR:记录的编号
[root@longwang ~]# awk '{print NR,$0}' /etc/issue /etc/centos-release
1 \S
2 Kernel \r on an \m
3
4 CentOS Linux release 8.1.1911 (Core)
范例:取ifconfig输出结果中的IP地址
[root@CentOS-8 ~]# ifconfig eth0 | awk '/netmask/{print $2}'
172.31.0.20
[root@CentOS-8 ~]# ifconfig eth0 | awk 'NR==2{print $2}'
172.31.0.20
范例:
[root@CentOS-8 ~]# awk -F: '{print NR}' /etc/passwd
1
2
3
...
45
[root@CentOS-8 ~]# awk -F: 'END{print NR}' /etc/passwd
45
[root@CentOS-8 ~]# awk -F: 'BEGIN{print NR}' /etc/passwd
0
FNR:各文件分别计数,记录的编号
[root@CentOS-8 ~]# awk '{print FNR}' /etc/fstab /etc/inittab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@CentOS-8 ~]# awk '{print NR,$0}' /etc/issue /etc/redhat-release
1 \S
2 Kernel \r on an \m
3
4 CentOS Linux release 8.1.1911 (Core)
[root@CentOS-8 ~]# awk '{print FNR,$0}' /etc/issue /etc/redhat-release
1 \S
2 Kernel \r on an \m
3
1 CentOS Linux release 8.1.1911 (Core)
FILENAME:当前文件名
[root@CentOS-8 ~]# awk '{print FILENAME}' /etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
/etc/fstab
[root@CentOS-8 ~]# 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 8.1.1911 (Core)
ARGC:命令行参数的个数
[root@CentOS-8 ~]# awk '{print ARGC}' /etc/issue /etc/redhat-release
3
3
3
3
[root@CentOS-8 ~]# awk 'BEGIN{print ARGC}' /etc/issue /etc/redhat-release
3
ARGV:数组,保存的是命令行所给定的各参数,每一个参数:ARGV[0],…
[root@CentOS-8 ~]# awk 'BEGIN{print ARGV[0]}' /etc/issue /etc/redhat-release
awk
[root@CentOS-8 ~]# awk 'BEGIN{print ARGV[1]}' /etc/issue /etc/redhat-release
/etc/issue
[root@CentOS-8 ~]# awk 'BEGIN{print ARGV[2]}' /etc/issue /etc/redhat-release
/etc/redhat-release
[root@CentOS-8 ~]# awk 'BEGIN{print ARGV[3]}' /etc/issue /etc/redhat-release
自定义变量是区分字符大小写的,使用下面方式进行赋值
-v var=value
在program中直接定义
范例:
[root@CentOS-8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{print test1,test2}'
test2=hello,gawk
[root@C[root@CentOS-8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{test1=test2="hello,gawk";print test1,test2}'
hello,gawk hello,gawkentOS-8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{test1=test2="hello,gawk";print test1,test2}'
hello,gawk hello,gawk
[root@CentOS-8 ~]# awk -v test1=test2="hello,gawk" 'BEGIN{test1=test2="hello,gawk";print test1,test2}'
hello,gawk hello,gawk
范例:
[root@CentOS-8 ~]# awk -v test='hello gawk' '{print test}' /etc/fstab
[root@CentOS-8 ~]# awk -v test='hello gawk' 'BEGIN{print test}'
[root@CentOS-8 ~]# awk 'BEGIN{test="hello,gawk";print test}'
[root@CentOS-8 ~]# awk -F: '{sex="male";print $1,sex,age;age=18}' /etc/passwd
[root@CentOS-8 ~]# cat awkscript
{print script,$1,$2}
[root@CentOS-8 ~]# awk -F: -f awkscript script="awk" /etc/passwd
BEGIN{}:仅在开始处理文件中的文本之前执行一次
END{}:仅在文本处理完成之后执行一次
printf 可以实现格式化输出
printf “FORMAT”, item1, item2, ...
说明:
必须指定FORMAT
不会自动换行,需要显式给出换行控制符 \n
FORMAT中需要分别为后面每个item指定格式符
格式符:与item一一对应
%s:显示字符串
%d, %i:显示十进制整数
%f:显示为浮点数
%e, %E:显示科学计数法数值
%c:显示字符的ASCII码
%g, %G:以科学计数法或浮点形式显示数值
%u:无符号整数
%%:显示%自身
修饰符
#[.#] 第一个数字控制显示的宽度;第二个#表示小数点后精度,如:%3.1f
- 左对齐(默认右对齐) 如:%-15s
+ 显示数值的正负符号 如:%+d
范例:
awk -F: '{printf "%s",$1}' /etc/passwd
awk -F: '{printf "%s\n",$1}' /etc/passwd
awk -F: '{printf "%20s\n",$1}' /etc/passwd
awk -F: '{printf "%-20s\n",$1}' /etc/passwd
awk -F: '{printf "%-20s %10d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %s\n",$1}' /etc/passwd
awk -F: '{printf “Username: %sUID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %25sUID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "Username: %-25sUID:%d\n",$1,$3}' /etc/passwd