文章目录
取一行内的信息-F:设置分隔符(默认为空格);NR:行数;NF最后的;$():第几个字段-F []+ 设置多个分隔符
匹配:/ /tee:将输出结果输入到文本中并覆盖BEGIN{}:在打印命令执行之前执行的命令;END{}:在打印命令执行后执行的命令输出时可以换行(\n),空格(\t)判断awk自带变量FILENAME:文件名FNR:总行数FS:设置分隔符,与-F等价NR:已读的记录数,相当于一共有多少行、最大值、最后一个值
赋值printf可以设置输出空行列值求和内置字符串函数gusb:将每行第一次匹配到的字符替换index:返回字符串中指定字符出现的位置length:返回所需字符串长度split:如果有一字符串,包含一指定分隔符,将之划分成一个数组sub:使用sub发现并替换模式的第一次出现位置substr:按照起始位置及长度返回字符串的一部分
printf 修饰符%c%f向一行awk命令传值awk脚本文件"ERROR*":awk脚本过滤出错误行的出现频率,使得每一个失败记录只对应一个错误行OFS:脚本中修改分隔符
取一行内的信息
取第二行的第一个域内的信息
[root@localhost ~]# head -2 passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@localhost ~]# awk -F: 'NR==2{print $1}' passwd
bin
-F:设置分隔符(默认为空格);NR:行数;NF最后的;$():第几个字段
取第一行的整行信息
[root@localhost ~]# awk -F: 'NR==1{print $0}' passwd
root:x:0:0:root:/root:/bin/bash
取第一行的第一个字段
[root@localhost ~]# awk -F: 'NR==1{print $1}' passwd
root
取第一行最后的字段
[root@localhost ~]# awk -F: 'NR==1{print $NF}' passwd
/bin/bash
取第一行倒数第二个字段
[root@localhost ~]# awk -F: 'NR==1{print $(NF-1)}' passwd
/root
-F []+ 设置多个分隔符
[root@localhost ~]# ip a|grep 'inet'
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
inet 192.168.220.10/24 brd 192.168.220.255 scope global ens33
inet6 fe80::4caa:3c40:20e9:48fa/64 scope link
[root@localhost ~]# ip a|grep 'inet' |awk -F '[/ ]+' 'NR==3{print $3}'
192.168.220.10
这里因为一行的开头是空格,并且空格算作分隔符,那么从定字符开始则是第二个字段
匹配:/ /
[root@localhost ~]# cat abc
M.Tansley 05/99 48311 8 40 44
J.Lulu 06/99 48317 9 24 26
P.Bunny 02/99 48 12 35 28
J.Troll 07/99 4842 12 26 26
L.Tansley 05/99 4712 12 30 28
[root@localhost ~]# awk '/M.Tansley/{print $2}' abc
05/99
tee:将输出结果输入到文本中并覆盖
[root@localhost ~]# cat 123
hello
[root@localhost ~]# awk '/J.Lulu/{print $2}' abc | tee 123
06/99
[root@localhost ~]# cat 123
06/99
BEGIN{}:在打印命令执行之前执行的命令;END{}:在打印命令执行后执行的命令
[root@localhost ~]# awk 'BEGIN{print "name date"} {print $1,$2}' abc
name date
M.Tansley 05/99
J.Lulu 06/99
P.Bunny 02/99
J.Troll 07/99
L.Tansley 05/99
[root@localhost ~]# awk 'BEGIN{print "name date"}{print $1,$2} END{print "hehe"}' abc
name date
M.Tansley 05/99
J.Lulu 06/99
P.Bunny 02/99
J.Troll 07/99
L.Tansley 05/99
hehe
输出时可以换行(\n),空格(\t)
[root@localhost ~]# cat abc
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
[root@localhost ~]# awk 'BEGIN{priname段带\t年龄"} {print $4"\t"$5}' abc
段带 年龄
Green 8
green 9
Yellow 12
Brown-3 12
Brown-2 12
[root@localhost ~]# awk 'BEGIN{print "段带\t年龄"} {print $4"\t"$5} END{print "-------\nhehe"'} abc
段带 年龄
Green 8
green 9
Yellow 12
Brown-3 12
Brown-2 12
-------
hehe
判断
if
[root@localhost ~]# awk '{if($5<10) print $0}' abc
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
匹配
[root@localhost ~]# awk '$3 ~ /48317/ {print$0}' abc
J.Lulu 06/99 48317 green 9 24 26
[root@localhost ~]# awk '$3 !~ /48317/ {print$0}' abc
M.Tansley 05/99 48311 Green 8 40 44
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
[root@localhost ~]# awk '$1 ~ /^J\....u$/' abc
J.Lulu 06/99 48317 green 9 24 26
J.RACu 06/99 48318 blue 10 25 27
[root@localhost ~]# awk '$4 ~ /(Green|green)/' abc
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
*if 匹配
[root@localhost ~]# awk '{if($5~/12/) print $0}' abc
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
[root@localhost ~]# awk '{if($5!~/12/) print $0}' abc
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
awk自带变量
FILENAME:文件名
[root@localhost ~]# awk 'END{print FILENAME}' abc
abc
FNR:总行数
[root@localhost ~]# awk 'END{print FNR}' passwd
21
[root@localhost ~]# cat passwd |wc -l
21
FS:设置分隔符,与-F等价
[root@localhost ~]# awk 'BEGIN{FS=":"} {print$1,$3}' passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
postfix 89
chrony 998
sshd 74
gluster 997
hzw 1000
NR:已读的记录数,相当于一共有多少行、最大值、最后一个值
[root@localhost ~]# awk 'END{print NR}' abc
6
[root@localhost network-scripts]# echo $PWD |awk -F/ '{print $NF}'
network-scripts
[root@localhost network-scripts]# basename /etc/sysconfig/network-scripts/
network-scripts
赋值
[root@localhost ~]# awk 'BEGIN{socer=25}{if($6 > socer)print $0}' abc
M.Tansley 05/99 48311 Green 8 40 44
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
[root@localhost ~]# awk '{if($1 ~ /J.Lulu/) $6=$6+26;print $1,$6,$7}' abc
M.Tansley 40 44
J.Lulu 50 26
J.RACu 25 27
P.Bunny 35 28
J.Troll 26 26
L.Tansley 30 28
[root@localhost ~]# awk 'NR==2 {if($1 ~ /J.Lulu/) $6=$6+26;print $1,$6,$7}' abc
J.Lulu 50 26
[root@localhost ~]# awk '{if($1 ~ /J.Lulu/) $1="TOM";print $1,$6,$7}' abc
M.Tansley 40 44
TOM 24 26
J.RACu 25 27
P.Bunny 35 28
J.Troll 26 26
L.Tansley 30 28
$1后面赋值需要加引号,以免$1把TOM作为变量,会报错
printf可以设置输出空行
[root@localhost ~]# awk 'BEGIN{print "name\t Difference"}{if($6<$7){$8=$7-$6;printf "%-15s %s\n",$1,$8}}' abc
name Difference
M.Tansley 4
J.Lulu 2
J.RACu 2
[root@localhost ~]# awk 'BEGIN{print "name\t Difference"}{if($6<$7){$8=$7-$6;printf "%15s %s\n",$1,$8}}' abc
name Difference
M.Tansley 4
J.Lulu 2
J.RACu 2
每个%s对应一个文本,按顺序对应,%后的设置也与文本相对应%s+数字:设置空多少行,从第一个字符开始%s -:向右对齐,没有-默认向左对齐
列值求和
[root@localhost ~]# awk '(total+=$7); END{print "The club student is: " total}' abc
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
J.RACu 06/99 48318 blue 10 25 27
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
The club student is: 179
/^ [^d ]/:以非d开头的文件
[root@localhost ~]# ll |awk '/^[^d]/{print $9"\t"$5}{total+=$5} END{print "total kb:"total}'
123 6
abc 324
passwd 946
samba 12
工作经历与面试题(1).txt 9504
total kb:10798
内置字符串函数
gusb:将每行第一次匹配到的字符替换
[root@localhost ~]# awk 'gsub(/12/,100){print $0}' abc
P.Bunny 02/99 48 Yellow 100 35 28
J.Troll 07/99 4842 Brown-3 100 26 26
L.Tansley 05/99 47100 Brown-2 100 30 28
index:返回字符串中指定字符出现的位置
[root@localhost ~]# awk 'BEGIN{print index("tomjerrytom","ry")}'
7
length:返回所需字符串长度
[root@localhost ~]# awk '$1=="M.Tansley"{print length($1)" "$1}' abc
9 M.Tansley
split:如果有一字符串,包含一指定分隔符,将之划分成一个数组
[root@localhost ~]# awk 'BEGIN{print split("123-456-256-326-436-37-3456",hzw,"-")}'
7
[root@localhost ~]# awk 'BEGIN{print split("123-456-256-326-436-37-3456",hzw,"#")}'
1
[root@localhost ~]# awk 'BEGIN{print split("123-456-256-326#436-37#3456",hzw,"#")}'
3
[root@localhost ~]# echo |awk 'BEGIN{print split("123-456-256-326#436-37#3456",hzw,"#")}{print hzw[1]}'
3
123-456-256-326
sub:使用sub发现并替换模式的第一次出现位置
sub(/匹配的字符/,"替换后的字符”,$(检测的域,要匹配的域或$0)
[root@localhost ~]# cat abc
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
J.RACu 06/99 48318 blue 10 25 27
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
[root@localhost ~]# awk '$1=="J.Lulu",sub(/24/,"29",$0)' abc
J.Lulu 06/99 48317 green 9 29 26
substr:按照起始位置及长度返回字符串的一部分
[root@localhost ~]# awk '"$1==J.Lulu" {print substr($1,3,6)}' abc
Tansle
Lulu
RACu
Bunny
Troll
Tansle
[root@localhost ~]# awk '$1=="J.Lulu" {print substr($1,3,6)}' abc
Lulu
[root@localhost ~]# awk '$1=="J.Lulu" {print substr($1,3)}' abc
Lulu
[root@localhost ~]# echo "mydoc.txt" |awk '{print substr($0,1,5)}'
mydoc
[root@localhost ~]# echo "mydoc.txt" |awk '{print substr($0,6)}'
.txt
printf 修饰符
% c ASCII字符 % d 整数 % e 浮点数,科学记数法 % f 浮点数,例如(1 2 3 . 4 4) % g awk决定使用哪种浮点数转换e或者f % o 八进制数 % s 字符串 % x 十六进制数
%c
[root@localhost ~]# echo 100 |awk '{printf "%c\n",$0}'
d
%f
默认为小数点后6位
[root@localhost ~]# awk 'BEGIN{printf "%f\n",100}'
100.000000
[root@localhost ~]# awk 'BEGIN{printf "%.2f\n",100}'
100.00
向一行awk命令传值
[root@localhost ~]# awk '{if($5 < age) print $0}' age=12 abc
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
J.RACu 06/99 48318 blue 10 25 27
awk脚本文件
[root@localhost ~]# ./a.awk a
student date number grade age point max
awk: ./a.awk:4: fatal: cannot open file `a' for reading (没有那个文件或目录)
[root@localhost ~]# ./a.awk abc
student date number grade age point max
M.Tansley 05/99 48311 Green 8 40 44
J.Lulu 06/99 48317 green 9 24 26
J.RACu 06/99 48318 blue 10 25 27
P.Bunny 02/99 48 Yellow 12 35 28
J.Troll 07/99 4842 Brown-3 12 26 26
L.Tansley 05/99 4712 Brown-2 12 30 28
所有人总分: 180
平均分: 30
[root@localhost ~]# cat a.awk
#!/usr/bin/awk -f
BEGIN{
print "student date number grade age point max"
}
(total+=$6)
END{
print "所有人总分: " total
print "平均分: " total/NR
}
“ERROR*”:awk脚本过滤出错误行的出现频率,使得每一个失败记录只对应一个错误行
[root@localhost ~]# cat def
error*
error*
error*
error*
abc
error*
error*
error*
error*
qwe
error*
error*
[root@localhost ~]# cat b.awk
#!/usr/bin/awk -f
BEGIN{
error_line=""
}
{
if($0=="error*" && error_line=="error*")
next;
error_line=$0;
print
}
[root@localhost ~]# ./b.awk def
error*
abc
error*
qwe
error*
OFS:脚本中修改分隔符
[root@localhost ~]# cat c.awk
#!/usr/bin/awk -f
BEGIN{
FS=":"
OFS="*"
}
{
print $1,$3
}
[root@localhost ~]# ./c.awk passwd
root*0
bin*1
daemon*2
adm*3
lp*4
sync*5
shutdown*6
halt*7
mail*8
operator*11
games*12
ftp*14
nobody*99
systemd-network*192
dbus*81
polkitd*999
postfix*89
chrony*998
sshd*74
gluster*997
hzw*1000