AWK笔记

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

awk知识学习。
Good Good Study,Day Day Up.


提示:以下是本篇文章正文内容,下面案例可供参考

一、awk是什么?

1、awk是一种编程语言,用于在 linux/unix 下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。

2、awk 支持用户自定义函数和动态正则表达式等先进功能,是 linux/unix 下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。

3、awk 的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到标准输出 (屏幕),如果没有指定模式,则所有被操作所指定的行都被处理

4、awk 分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是 Alfred Aho、Brian Kernighan、Peter Weinberger。gawk 是 awk 的 GNU 版本,它提供了 Bell 实验室和 GNU 的一些扩展。

二、awk的命令格式和选项

###语法形式
awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)

三、脚本的基本结构

awk 'BEGIN{ commands } { commands } END{ commands }' file

一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块3部分组成,这三个部分都是可选的,任一部分都可以不出现在脚本中,脚本通常被单引号或双引号引起来。

工作原理

  • 第一步:执行BEGIN{ commands }语句块中的语句;
  • 第二步:从文件或标准输入(stdin)读取一行,然后执行{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕;
  • 第三步:当执行完前面步骤后,执行END{ commands }语句块

四、awk内置变量

名称释义
FS表示当前的分隔符(默认为空格)
RS表示当前的分隔符(默认为换行符\n)
OFS输出字段分隔符
ORS输出记录分隔符
NR表示读取到当前文件的第几行
NF表示当前文件有几列
FILENAME当前处理的文件名
FNR也是读取文件的行数,但是和NR不同的是当读取的文件有两个或两个以上时,NR读取完一个文件,行数继续增加而FNR重新从1开始记录
$数字取某一列
$0取出这一行

举例:

  • FS与OFS
[root@xxx ~] awk 'BEGIN{ FS=":" }{print $1,$2}' /etc/passwd | head -n 5
root x
bin x
daemon x
adm x
lp x
[root@xxx ~] awk 'BEGIN{ FS=":";OFS="@" }{print $1,$2}' /etc/passwd | head -n 5
root@x
bin@x
daemon@x
adm@x
lp@x
[root@xxx ~]#

  • RS与ORS
[root@xxx ~] cat t.txt
1234567890abcd@hhh888
[root@xxx ~] awk 'BEGIN{ RS="9|@" }{print $1}' t.txt
12345678
0abcd
hhh888
[root@xxx ~]#
[root@xxx ~] awk 'BEGIN{ RS="hhh" }{print $1}' t.txt
1234567890abcd@
888
[root@xxx ~] awk 'BEGIN{ RS="hhh";ORS="HHH" }{print $1}' t.txt
1234567890abcd@HHH888HHH[root@xxx ~]#

利用RS一次性读取一段内容

(base) [root@master ~]# ifconfig
enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.101  netmask 255.255.255.0  broadcast 192.168.56.255
        inet6 fe80::6097:4430:7856:944a  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:90:e9:70  txqueuelen 1000  (Ethernet)
        RX packets 6202  bytes 426650 (416.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9133  bytes 1070564 (1.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s17: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::bb28:18f0:425d:feaa  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:3b:04:27  txqueuelen 1000  (Ethernet)
        RX packets 36  bytes 3789 (3.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 47  bytes 4391 (4.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

(base) [root@master ~]# ifconfig | awk 'BEGIN{RS=""}''!/^lo/{print}'
enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.101  netmask 255.255.255.0  broadcast 192.168.56.255
        inet6 fe80::6097:4430:7856:944a  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:90:e9:70  txqueuelen 1000  (Ethernet)
        RX packets 8304  bytes 567472 (554.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 11697  bytes 1367576 (1.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
enp0s17: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::bb28:18f0:425d:feaa  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:3b:04:27  txqueuelen 1000  (Ethernet)
        RX packets 36  bytes 3789 (3.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 47  bytes 4391 (4.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

(base) [root@master ~]# ifconfig | awk 'BEGIN{RS=""}''!/^lo/{print $6}'
192.168.56.101
10.0.2.15
(base) [root@master ~]#

  • NR与NF
[root@xxx ~] awk -F ':' '{print $NR"\t"$NF"\t"$0}' /etc/passwd | head -n 5
root    /bin/bash       root:x:0:0:root:/root:/bin/bash
x       /sbin/nologin   bin:x:1:1:bin:/bin:/sbin/nologin
2       /sbin/nologin   daemon:x:2:2:daemon:/sbin:/sbin/nologin
4       /sbin/nologin   adm:x:3:4:adm:/var/adm:/sbin/nologin
lp      /sbin/nologin   lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  • FNR与FILENAME
[root@xxx ~] cat t.txt
1
2
3
[root@xxx ~] cat y.txt
1
2
3
4
5
[root@xxx ~] awk 'NR==FNR{ print "read "FILENAME " now! reading num "NR" row.FNR="FNR;next}{print "read "FILENAME" now! reading num "FNR" row.NR="NR}' t.txt y.txt
read t.txt now! reading num 1 row.FNR=1
read t.txt now! reading num 2 row.FNR=2
read t.txt now! reading num 3 row.FNR=3
read y.txt now! reading num 1 row.NR=4
read y.txt now! reading num 2 row.NR=5
read y.txt now! reading num 3 row.NR=6
read y.txt now! reading num 4 row.NR=7
read y.txt now! reading num 5 row.NR=8
[root@xxx ~]#

五、awk内置函数

·字符串函数

1、split
awk的内建函数split允许你把一个字符串分隔为单词并存储在数组中。你可以自己定义域分隔符或者使用现在FS(域分隔符)的值。
格式:

split (string, array, field separator)
split (string, array) #如果第三个参数没有提供,awk就默认使用当前FS值。
[root@xxx ~] time="12:34:56"
[root@xxx ~] echo $time | awk 'BEGIN{ORS=" "}{split($0,a,":");for (i in a) print a[i]}'
12 34 56 [root@xxx ~]#
[root@xxx ~] echo $time | awk '{split($0,a,":");for (i in a) print a[i]}'
12
34
56
[root@xxx ~] echo $time | awk '{split($0,a,":");print a[1],a[2],a[3]}'
12 34 56
[root@xxx ~]#
[root@xxx ~] cat test.txt
Tom    2012-12-11      car     53000
John   2013-01-13      bike    41000
vivi    2013-01-18      car     42800
Tom    2013-01-20      car     32500
John   2013-01-28      bike    63500
###求每个人一月份的工资###
[root@xxx ~] awk '{split($2,a,"-");if(a[2]==01){sum[$1]+=$4}}END{for(i in sum) print i,sum[i]}' test.txt | column -t
vivi      42800
Tom     32500
John    104500

2、substr
返回从起始位置起,指定长度之子字符串;若未指定长度,则返回从起始位置到字符串末尾的子字符串。
格式:

substr(s,p)返回字符串s中从p开始的后缀部分
substr(s,p,n)返回字符串s中从p开始长度为n的后缀部分
[root@xxx ~] echo "abcd12345" | awk '{print substr($0,2,3)}'
bcd
[root@xxx ~]# echo "abcd12345" | awk '{print substr($0,5)}'
12345

3、length
length函数返回没有参数的字符串的长度。length函数返回整个记录中的字符数

[root@xxx ~] cat test.txt
1234 99999 88888
aaaaa jjjjj HUIASHDA
123 &%@$!& cnsdo123
[root@xxx ~] awk '{print length}' test.txt
16
20
19
[root@xxx ~]#

4、gsub
gsub函数则使得在所有正则表达式被匹配的时候都发生替换。gsub(regular expression,subsitution string,target string);简称gsub (r,s,t)

举例:把一个文件里面所有包含a的行里面的a替换成~,然后输出整行。

[root@xxx ~] cat test.txt
abcdefg ojdka
123456abkij afas
OAJDSahuq 213sfd
s!@a$ @123(((%+
[root@xxx ~] awk '$0~ /a/{print gsub("a","~",$0),$0}' test.txt
2 ~bcdefg ojdk~
3 123456~bkij ~f~s
1 OAJDS~huq 213sfd
1 s!@~$ @123(((%+
[root@xxx ~]

5、next
在awk中,如果调用next,那么next之后的命令就都不再执行了,此行文本的处理到此结束,继续读取下一条记录并操作

[root@xxx ~] cat test.txt
abcdefg ojdka
123456abkij afas
OAJDSahuq 213sfd
s!@a$ @123(((%+
[root@xxx ~] awk '{if(NR==1) next;print $0}' test.txt
123456abkij afas
OAJDSahuq 213sfd
s!@a$ @123(((%+
[root@xxx ~]#

6、tolower(str)/toupper(str)
字符串str中每个大写字符将更改为小写/大写

[root@xxx ~] cat t.txt
abcdEFGH
UVWxyz12
[root@xxx ~] awk '{print tolower($0)}' t.txt
abcdefgh
uvwxyz12
[root@xxx ~] awk '{print toupper($0)}' t.txt
ABCDEFGH
UVWXYZ12
[root@xxx ~]#
  • 时间函数

1、strftime([format [, timestamp]])
格式化时间输出,将时间戳转为时间字符串

[root@xxx ~] awk 'BEGIN{print strftime("Time = %m/%d/%Y %H:%M:%S", systime())}'
Time = 05/26/2023 10:46:53
[root@xxx ~] awk 'BEGIN{print strftime("Time = %F %T%z", systime())}'
Time = 2023-05-26 10:47:05+0800
[root@xxx ~]#

五、小练习

1、文本拼接

  1. NR与FNR
    解释说明:NR,表示awk开始执行程序后所读取的数据行数。FNR,与NR功用类似,不同的是awk每打开一个新文件,FNR便从0重新累计。

    下面例子中,当读取到前两行时,NR=FNR,此时执行第一个{}中的代码;从第三行(b.txt的第一行)开始,NR=3,FNR=1,NR!=FNR,执行第二个{}中的代码。(行数少的文件为a.txt)

[root@xxxx ~]cat a.txt
张三|000001
李四|000002
[root@xxxx ~]cat b.txt
000001|10
000001|20
000002|30
000002|15

[root@xxxx ~]awk -F '|' 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' a.txt b.txt
张三|000001|10
张三|000001|20
李四|000002|30
李四|000002|15

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 31
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值