一、awk 数组
1.1 数组结构
people[police]=110
people[doctor]=120
[root@creditease awk]# awk 'BEGIN{word[0]="credit";word[1]="easy";print word[0],word[1]}'
credit easy
[root@creditease awk]# awk 'BEGIN{word[0]="credit";word[1]="easy";for(i in word)print word[i]}'
credit
easy
1.2 数组分类
索 引数组:以数字为下标
关联数组:以字符串为下标
1.3 awk 关联数组
现有如下文本,格式如下:即左边是随机字母,右边是随机数字, 即将相同的字母后面的数字加在一起,按字母的顺序输出
a 1
b 3
c 2
d 7
b 5
a 3
g 2
f 6
以1为下标,创建数组a[1]=a[1]+2(a[1]+=2)然后配合 END 和 for 循环输出结果:
[root@creditease awk]# awk '{a[$1]=a[$1]+$2}END{for(i in a)print i,a[i]}' jia.txt
a 4
b 8
c 2
d 7
f 6
g 2
注意:for(i in a) 循环的顺序不是按照文本内容的顺序来处理的,排序可以在命令后加sort排序
1.4 awk 索引数组
以数字为下标的数组 seq 生成 1-10 的数字,要求只显示计数行
[root@creditease awk]# seq 10|awk '{a[NR]=$0}END{for(i=1;i<=NR;i+=2){print a[i]}}'
1
3
5
7
9
seq 生成 1-10 的数字,要求不显示文件的后 3 行
[root@creditease awk]# seq 10|awk '{a[NR]=$0}END{for(i=1;i<=NR-3;i++){print a[i]}}'
1
2
3
4
5
6
7
解析:改变i的范围即可,多用于不显示文件的后几行
1.5 awk 数组实战去重
a++ 和 ++a
[root@creditease awk]# awk 'BEGIN{print a++}'
0
[root@creditease awk]# awk 'BEGIN{print ++a}'
1
[root@creditease awk]# awk 'BEGIN{a=1;b=a++;print a,b}'
2 1
[root@creditease awk]# awk 'BEGIN{a=1;b=++a;print a,b}'
2 2
注:
都是 b = a+1
b=a++ 先把 a 的值赋予b,然后 a + 1
b=++a 先执行a+1,然后把a的值赋予b
对一下文本进行去重处理 针对第二列去重
[root@creditease awk]# cat qc.txt
2018/10/20 xiaoli 13373305025
2018/10/25 xiaowang 17712215986
2018/11/01 xiaoliu 18615517895
2018/11/12 xiaoli 13373305025
2018/11/19 xiaozhao 15512013263
2018/11/26 xiaoliu 18615517895
2018/12/01 xiaoma 16965564525
2018/12/09 xiaowang 17712215986
2018/11/24 xiaozhao 15512013263
解法一:
[root@creditease awk]# awk '!a[$2]++' qc.txt
2018/10/20 xiaoli 13373305025
2018/10/25 xiaowang 17712215986
2018/11/01 xiaoliu 18615517895
2018/11/19 xiaozhao 15512013263
2018/12/01 xiaoma 16965564525
解析:
!a[$3]++是模式(条件),命令也可写成awk '!
a[$3]=a[$3]+1{print $0}' qc.txt
a[$3]++ ,“++”在后,先取值后加一
!a[$3]=a[$3]+1:是先取a[$3]的值,比较“!a[$3]”是否符合条件(条件非0),后加1
注意:此方法去重后的结果显示的是文本开头开始的所有不重复的行
解法二:
[root@creditease awk]# awk '++a[$2]==1' qc.txt
2018/10/20 xiaoli 13373305025
2018/10/25 xiaowang 17712215986
2018/11/01 xiaoliu 18615517895
2018/11/19 xiaozhao 15512013263
2018/12/01 xiaoma 16965564525
解析:
++a[$3]==1是模式(条件),也可写成a[$3]=a[$3]+1==1即只有当条件(a[$3]+1的结果)为1的时候才打印出内容
++a[$3] ,“++”在前,先加一后取值
++a[$3]==1:是先加1,后取a[$3]的值,比较“++a[$3]”是否符合条件(值为1)
注意:此方法去重后的结果显示的是文本开头开始的所有不重复的行
解法三:
[root@creditease awk]# awk '{a[$2]=$0}END{for(i in a){print a[i]}}' qc.txt
2018/11/12 xiaoli 13373305025
2018/11/26 xiaoliu 18615517895
2018/12/01 xiaoma 16965564525
2018/12/09 xiaowang 17712215986
2018/11/24 xiaozhao 15512013263
解析:
注意此方法去重后的结果显示的是文本结尾开始的所有不重复的行
1.6 awk 处理多个文件(数组、NR、FNR)
使用 awk 取 file.txt 的第一列和 file1.txt 的第二列然后重定向到一个新文件 new.txt 中
[root@creditease awk]# cat file1.txt
a b
c d
e f
g h
i j
[root@creditease awk]# cat file2.txt
1 2
3 4
5 6
7 8
9 10
[root@creditease awk]# awk 'NR==FNR{a[FNR]=$1}NR!=FNR{print a[FNR],$2}' file1.txt file2.txt
a 2
c 4
e 6
g 8
i 10
解析:NR==FNR处理的是第一个文件,NR!=FNR处理的是第二个文件.
注意:当两个文件NR(行数)不同的时候,需要把行数多的放前边.
解决方法:把行数多的文件放前边,行数少的文件放后边.
把输出的结果放入一个新文件new.txt中:
[root@creditease awk]# awk 'NR==FNR{a[FNR]=$1}NR!=FNR{print a[FNR],$2>"new.txt"}' file1.txt file2.txt
[root@creditease awk]# cat new.txt
a 2
c 4
e 6
g 8
i 10
1.7 awk 分析日志文件,统计访问网站的个数
[root@creditease awk]# cat url.txt
http://www.baidu.com
http://mp4.video.cn
http://www.qq.com
http://www.listeneasy.com
http://mp3.music.com
http://www.qq.com
http://www.qq.com
http://www.listeneasy.com
http://www.listeneasy.com
http://mp4.video.cn
http://mp3.music.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
[root@creditease awk]# awk -F "[/]+" '{h[$2]++}END{for(i in h) print i,h[i]}' url.txt
www.qq.com 3
www.baidu.com 5
mp4.video.cn 2
mp3.music.com 2
www.crediteasy.com 3
二、awk 简单语法
2.1 函数 sub gsub
替换功能
格式:sub(r, s ,目标) gsub(r, s ,目标)
[root@creditease awk]# cat sub.txt
ABC DEF AHI GKL$123
BAC DEF AHI GKL$213
CBA DEF GHI GKL$321
[root@creditease awk]# awk '{sub(/A/,"a");print $0}' sub.txt
aBC DEF AHI GKL$123
BaC DEF AHI GKL$213
CBa DEF GHI GKL$321
[root@creditease awk]# awk '{gsub(/A/,"a");print $0}' sub.txt
aBC DEF aHI GKL$123
BaC DEF aHI GKL$213
CBa DEF GHI GKL$321
注:sub只会替换行内匹配的第一次内容;相当于sed ‘s###’
gsub 会替换行内匹配的所有内容;相当于sed ‘s###g’
[root@creditease awk]# awk '{sub(/A/,"a",$1);print $0}' sub.txt
aBC DEF AHI GKL$123
BaC DEF AHI GKL$213
CBa DEF GHI GKL$321
练习:
0001|20081223efskjfdj|EREADFASDLKJCV
0002|20081208djfksdaa|JDKFJALSDJFsddf
0003|20081208efskjfdj|EREADFASDLKJCV
0004|20081211djfksdaa1234|JDKFJALSDJFsddf
以'|'为分隔, 现要将第二个域字母前的数字去掉,其他地方都不变, 输出为:
0001|efskjfdj|EREADFASDLKJCV
0002|djfksdaa|JDKFJALSDJFsddf
0003|efskjfdj|EREADFASDLKJCV
0004|djfksdaa1234|JDKFJALSDJFsddf
方法:
awk -F '|' 'BEGIN{OFS="|"}{sub(/[0-9]+/,"",$2);print $0}' sub_hm.txt
awk -F '|' -v OFS="|" '{sub(/[0-9]+/,"",$2);print $0}' sub_hm.txt
2.2 if 和 slse 的用法
内容:
AA
BC
AA
CB
CC
AA
结果:
AA YES
BC NO YES
AA YES
CB NO YES
CC NO YES
AA YES
1) [root@creditease awk]# awk '{if($0~/AA/){print $0" YES"}else{print $0" NO YES"}}' ifelse.txt
AA YES
BC NO YES
AA YES
CB NO YES
CC NO YES
AA YES
解析:使用if和else,if $0匹配到AA,则打印$0 "YES",else反之打印$0 " NO YES"。
2)[root@creditease awk]# awk '$0~/AA/{print $0" YES"}$0!~/AA/{print $0" NO YES"}' ifelse.txt
AA YES
BC NO YES
AA YES
CB NO YES
CC NO YES
AA YES
解析:使用正则匹配,当$0匹配AA时,打印出YES,反之,打印出“NO YES”
2.3 next 用法
如上题,用 next 来实现
next :跳过它后边的所有代码
[root@creditease awk]# awk '$0~/AA/{print $0" YES";next}{print $0" NO YES"}' ifelse.txt
AA YES
BC NO YES
AA YES
CB NO YES
CC NO YES
AA YES
解析:
{print $0" NO YES"}:此动作是默认执行的,当前边的$0~/AA/匹配,就会执行{print $0" YES";next}
因为action中有next,所以会跳过后边的action。
如果符合$0~/AA/则打印YES ,遇到next后,后边的动作不执行;如果不符合$0~/AA/,会执行next后边的动作;
next前边的(模式匹配),后边的就不执行,前边的不执行(模式不匹配),后边的就执行。
2.4 printf 不换行输出以及 next 用法
printf :打印后不换行
如下文本,如果 Description:之后为空,将其后一行内容并入此行。
Packages: Hello-1
Owner: me me me me
Other: who care?
Description:
Hello world!
Other2: don't care
想要结果:
Packages: Hello-1
Owner: me me me me
Other: who care?
Description: Hello world!
Origial-Owner: me me me me
Other2: don't care
1)[root@creditease awk]# awk '/^Desc.*:$/{printf $0}!/Desc.*:$/{print $0}' printf.txt
Packages: Hello-1
Owner: me me me me
Other: who care?
Description:Hello world!
Other2: don't care
解析:使用正则匹配,匹配到'/^Desc.*:$/,就使用printf打印(不换行),不匹配的打印出整行。
2)使用if和else实现
[root@creditease awk]# awk '{if(/Des.*:$/){printf $0}else{print $0}}' printf.txt
Packages: Hello-1
Owner: me me me me
Other: who care?
Description:Hello world!
Other2: don't care
3)使用next实现
[root@creditease awk]# awk '/Desc.*:$/{printf $0;next}{print $0}' printf.txt
Packages: Hello-1
Owner: me me me me
Other: who care?
Description:Hello world!
Other2: don't care
注:可简写成awk '/Desc.*:$/{printf $0;next}1'
printf.txt ## 1是pattern(模式),默认action(动作)是{print $0}
2.5 去重后计数按要求重定向到指定文件
文本如下,要求计算出每项重复的个数,然后把重复次数大于 2 的放入 gt2.txt 文件中,把重复次数小于等于 2 的放入 le2.txt 文件中
[root@creditease files]# cat qcjs.txt
aaa
bbb
ccc
aaa
ddd
bbb
rrr
ttt
ccc
eee
ddd
rrr
bbb
rrr
bbb
[root@creditease awk]# awk '{a[$1]++}END{for(i in a){if(a[i]>2){print i,a[i]>"gt2.txt"}else{print i,a[i]>"le2.txt"}}}' qcjs.txt
[root@creditease awk]# cat gt2.txt
rrr 3
bbb 4
[root@creditease awk]# cat le2.txt
aaa 2
ccc 2
eee 1
ttt 1
ddd 2
解析:{print },或括号中打印后可直接重定向到一个新文件,文件名用双引号引起来。如: {print $1 >"xin.txt"}
三、awk 需注意事项
a)NR==FNR ##不能写成 NR=FNR(=在 awk 中是赋值的意思)
b)NR!=FNR ##NR 不等于 FNR
c){a=1;a[NR]} 这样会报错:同一条命令中变量和数组名不能重复 d)printf 输出的时候不换行
e){print },或括号中打印后可直接重定向到一个新文件,文件名用双引号引起来。如: {print $1 >“xin.txt”}
f)当模式(条件)是 0 的时候,后边的动作不执行,!0 的时候后边动作才执行。
本文转载自宜信技术学院网站。
原文链接:http://college.creditease.cn/detail/262
更多内容推荐
Linux 常用基础命令(巨全)
@[toc]Linux系统下,以.开头的都是隐藏文件Linux中..表示上一级目录,.表示当前目录长格式引导:-- 引导单词短格式引导:- 引导字母
2022-11-01
11|字符串(下):Python 是如何处理单词的?
2022-11-16
常用特殊符号大全
常用特殊符号大全
2021-09-11
3.2 面试技巧和面试题精讲
2023-09-27
零售行业商业分析案例:人货场分析
2022-12-30
正则表达式.01 - 元字符
正则,就是正则表达式,英文是 Regular Expression,简称 RE。顾名思义,正则其实就是一种描述文本内容组成规律的表示方式。简单的说就是用来描述字符串的规则。它的强大之处在于可以查找符合某个规则的文本。
2021-03-06
10|Prompt 工具介绍:FlowGPT
2023-03-16
4. SparkSQL 整合其它外部数据源
2023-09-08
oeasy 教您玩转 vim - 14 - # 行头行尾
行头行尾回忆上节课内容🤔
2021-08-12
一文让你学会如何用代码判断 "24" 点
“24点”是一种数学游戏,正如象棋、围棋一样是一种人们喜闻乐见的娱乐活动。它始于何年何月已无从考究,但它以自己独具的数学魅力和丰富的内涵正逐渐被越来越多的人们所接受。
Python 应用之计算阶乘
阶乘是基斯顿·卡曼(Christian Kramp,1760~1826)于 1808 年发明的运算符号。一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,通俗的讲也就是按顺序从1乘到n,所得的那个数就是n的阶乘。0的阶乘为1,自然数n的阶乘写作n!。即:0!= 11!
2022-10-02
KMP —— 字符串分析算法
大家可能觉得 KMP 这个算法的名字很特别、很怪,因为 KMP 它并不是三个英文单词的开头,而是三个计算机科学家的名字。发明这个算法的三位计算机科学家分别为:Knuth、Morris、Pratt。第一个是大家都非常熟悉的 Donald Ervin Knuth (高德纳)
2020-12-07
上古神器 sed 教程详解,小白也能看得懂
熟悉 Linux 的同学一定知道大名鼎鼎的 Linux 三剑客,它们是 grep、awk、sed,我们今天要聊的主角就是 sed。
2021-02-06
oeasy 教您玩转 vim - 15 - # 行内查找
行头行尾回忆上节课内容🤔
2021-08-13
Python 应用之验证码验证
用户登录网站经常需要输入验证码,验证码包含大小写字母和数字,随机出现。用户输入验证码时不区分大小写,只要各字符出现顺序正确即可通过验证。 请写一个程序完成验证码的匹配验证,随机生成四位数的验证码如Qs2X(生成数字概率为1/5,大写字母和小写字
2022-10-07
特别加餐 | ChatGPT 类 AI 聊天机器人能看懂正则表达式?
我们今天的主题就聚焦在正则表达式与ChatGPT类AI智能聊天机器人,看看AI聊天机器人能在哪些方面帮助我们更好地使用正则表达式。
2023-05-31
一文带你了解两种 Transformer 文字识别方法
摘要:受Transformer模型的启发,目前一些学者将该结构应用到文本行识别中,以替代RNN,取得了良好的效果,如在HGA-STR和 SRN。
2020-11-27
进制转换、原码、反码、补码及位运算详解
对于进制换行进行详细的案例解析,原码、反码、补码的规则及在位运算时的应用示例,还有位运算符的规则及示例详解。
2022-10-20
oeasy 教您玩转 vim - 16 - # 行内贴靠
行头行尾回忆上节课内容🤔
2021-08-14
推荐阅读
04. 高效沟通的第一只拦路虎——我是对的
2023-10-17
2023-11-11:用 go 语言,字符串哈希 + 二分的例题。 给定长为 n 的源串 s,以及长度为 m 的模式串 p, 要求查找源串中有多少子串与模式串匹配, s‘ 与 s 匹配,当且仅当 s‘ 与 s
2023-11-11
17. 学会在沟通中更新思维:打造高效团队从有效的沟通开始
2023-10-17
软件测试|Python 删除列表元素的 3 种方法,你都会吗?
2023-10-10
第 03 节 关系信任:用情感绑架客户
2023-10-17
DNS 服务器
2022-11-20
2023-07-07:给出两个字符串 str1 和 str2。 返回同时以 str1 和 str2 作为子序列的最短字符串。 如果答案不止一个,则可以返回满足条件的任意一个答案。 输入:str1 =
2023-07-07
电子书
大厂实战PPT下载
换一换 刘一凡 | 快手 大数据服务负责人
吴锦晟 | 首都在线 生态副总裁、TGO 鲲鹏会(上海)学员
古思为 | NebulaGraph(星云图数据库)软件工程师,开发者布道师 《GitHub Copilot 实践课》专栏作者
评论