
一、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
更多内容推荐
10. INSERT:最简实现
2023-09-26
Linux 三剑客之 awk(2):awk 模块、变量与执行
Linux三剑客之awk系列文章第二篇,介绍awk结构模块与变量等。
解析器眼中的 Go 语言
代码其实就是按照约定格式编写的一堆字符串
oeasy 教您玩转 vim - 14 - # 行头行尾
行头行尾回忆上节课内容🤔
2021-08-12
oeasy 教您玩转 vim - 15 - # 行内查找
行头行尾回忆上节课内容🤔
2021-08-13
转义字符
2022-12-29
正则表达式 1
2022-12-29
如何编写 bash 自动补全脚本
最近我在为一个项目编写bash自动补全脚本,我非常喜欢这个功能。本文我会尽可能让读者熟悉编写一个bash自动补全脚本的流程。
Linux 三剑客之 awk(1):awk 简介与表达式示例
Linux三剑客之awk系列文章第一篇,介绍awk及正则表达式、操作符、比较表达式等。
刨根究底正则表达式之三:定界符与转义符
计算机世界中有一些非常基础、重要、应用广泛而又特别容易让人困惑的主题,比如字符编码、字节序(即大小端表示)浮点数实现、日期时间处理以及正则表达式等等,而正则表达式是其中的典型代表。然而正则表达式作为那种没用过的话,不觉得对自己有什么影响,一旦用过并且用熟练了,就再也回不去了的神器,要熟练掌握并能灵活运用,实非易事。 那到底应该怎样才能最高性价比地掌握正则表达式这个神器呢?这正是我写这个系列文章的目的。
产品思维和产品意识 · 什么是产品思维与意识(第一部分)
2023-09-18
12.Jenkins 实战 - CICD(下)
2023-09-30
【LeetCode】从上到下打印二叉树 Java 题解
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
2021-08-12
正则表达式.02 - 量词与贪婪
正则中有三种模式:贪婪模式、非贪婪模式、独占模式。这些模式会改变量词的匹配行为。
2021-03-07
特别加餐 | ChatGPT 类 AI 聊天机器人能看懂正则表达式?
我们今天的主题就聚焦在正则表达式与ChatGPT类AI智能聊天机器人,看看AI聊天机器人能在哪些方面帮助我们更好地使用正则表达式。
2023-05-31
OneData 之 OneService
阿里巴巴 OneData 体系中的 OneService ,其含义和主要内容
2020-05-17
Prolog 匹配
讨论 Prolog 中的匹配, 解释匹配(match)与相等的不同.
KMP —— 字符串分析算法
大家可能觉得 KMP 这个算法的名字很特别、很怪,因为 KMP 它并不是三个英文单词的开头,而是三个计算机科学家的名字。发明这个算法的三位计算机科学家分别为:Knuth、Morris、Pratt。第一个是大家都非常熟悉的 Donald Ervin Knuth (高德纳)
2020-12-07
JavaScript 学习(十)--- 正则表达式
JavaScript 当年入门时的笔记,欢迎后来者来借鉴指点
2021-06-26
正则表达式.01 - 元字符
正则,就是正则表达式,英文是 Regular Expression,简称 RE。顾名思义,正则其实就是一种描述文本内容组成规律的表示方式。简单的说就是用来描述字符串的规则。它的强大之处在于可以查找符合某个规则的文本。
2021-03-06
推荐阅读
软件测试|Python 删除列表元素的 3 种方法,你都会吗?
2023-10-10
进制转换、原码、反码、补码及位运算详解
2022-10-20
常用特殊符号大全
2021-09-11
第 08 集 招聘之 JD 撰写及面试技巧
2023-10-17
2023-11-11:用 go 语言,字符串哈希 + 二分的例题。 给定长为 n 的源串 s,以及长度为 m 的模式串 p, 要求查找源串中有多少子串与模式串匹配, s‘ 与 s 匹配,当且仅当 s‘ 与 s
2023-11-11
16. 有效与同事沟通技巧
2023-10-17
01. 销售经理的自我管理——完成角色转变(上)
2023-10-17
电子书

大厂实战PPT下载
换一换 
董纪伟 | 同盾科技 副总裁
吴琼Dante Wu | Akamai Technologies 解决方案工程师
付冰尧 | 小米 手机 IoT 团队 SRE 负责人






评论