写点什么

Linux 三剑客之 awk(3):awk 数组与语法

  • 2020-02-10
  • 本文字数:4621 字

    阅读完需:约 15 分钟

Linux三剑客之awk(3):awk数组与语法

一、awk 数组

1.1 数组结构

1560825858603035163.png


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[2(a[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


2020-02-10 21:061237

评论

发布
暂无评论
发现更多内容

教堂定制P4 LED屏幕安装:提升宗教体验

Dylan

数字化 LED显示屏 全彩LED显示屏 led显示屏厂家 户内led显示屏

AI数字人开发的技术框架

北京木奇移动技术有限公司

软件外包公司 AI数字人 AI数字人开发

生产排产的逻辑是什么?一文讲通!

积木链小链

数字化转型 智能制造 生产管理

时序数据库 TDengine 开源之夏项目全中选!年轻人的热爱从不是说说而已

TDengine

tdengine 开源 时序数据库

AI数字人开发的技术方案

北京木奇移动技术有限公司

软件外包公司 AI技术应用 AI数字人

基于 Amazon Nova Sonic 和 MCP 构建语音交互 Agent

亚马逊云科技 (Amazon Web Services)

全方位优化:智能化工器具库房管理综合解决方案

斯科信息

RFID解决方案 RFID工具库房 斯科信息 RFID技术

成功案例丨减重64%!Altair 解决方案助力3D打印铣削头实现轻量化

Altair RapidMiner

仿真 CAE hyperworks 3D打印 Radioss

CST软件无限平面圆孔RCS --- 单站, 单角多频,T和F求解器(远场),去耦平面

思茂信息

cst CST软件 CST Studio Suite

Post-Training on PAI (4):模型微调SFT、DPO、GRPO

阿里云大数据AI技术

人工智能 云计算 算法 模型微调 大模型微调实践

VMware ESXi 9.0.0.0100 发布 - 领先的裸机 Hypervisor

sysin

esxi

招商管理系统(源码+文档+讲解+演示)

深圳亥时科技

HCI发布《2025年洞察报告》

财见

BI 数据可视化平台建设(3)—首页性能提升实践

vivo互联网技术

前端 性能调优 BI可视化

没有专业IT团队?灯塔低代码平台让中小企业自己当"开发者"

中烟创新

嘉为蓝鲸DevOps平台:连续2年入选信通院数字化图谱,全链路赋能企业研发效能升级

嘉为蓝鲸

DevOps 智能运维 研运一体化

2015年9月微软安全更新汇总 - MS15-094至MS15-105漏洞修复

qife122

安全更新 Windows安全

清华大学软件学院院长王建民教授:AI 时代,如何从采数到用数?

Apache IoTDB

NocoBase CRM Demo 部署指南

NocoBase

开源 低代码 零代码 Demo CRM

云测试提前定位和解决问题 萤火故事屋 上架流程

万少

HarmonyOS NEXT

时序数据库 TimechoDB V2.0.5 发布 | 新增树转表视图、模型微调等功能

Apache IoTDB

大数据-43 Redis Lua脚本实战全解析 eval redis.call redis.pcall

武子康

Java lua redis 大数据 分布式

Console 纳管 Elasticsearch 9(二):日志监控

极限实验室

elasticsearch console

中烟创新入选2025全国企业“人工智能+”行动创新案例TOP100

中烟创新

不用写代码!2个小时,我自己搭了一套进销存系统,业务效率翻倍!

中烟创新

Golang基础笔记十二之defer、panic、error

Hunter熊

golang 后端 defer panic Error

百度视频云互动大模型SDK适配鸿蒙,让人机交互更智能、更开放

新消费日报

AI数字人的开发流程

北京木奇移动技术有限公司

软件外包公司 AI技术应用 AI数字人

微软发布安全公告2887505:IE远程代码执行漏洞分析与缓解方案

qife122

网络安全 浏览器安全

更新Mac软件有哪些方法 Mac软件如何管理待更新软件

阿拉灯神丁

appstore 应用程序 Mac软件 卸载清理软件 CleanMyMac X中文

Linux三剑客之awk(3):awk数组与语法_开源_秦伟_InfoQ精选文章