Shell脚本(5)——awk可以做什么

wils
wils

创作者俱乐部成员

awk是Shell脚本中使用最频繁、最重要的命令,linux中一切皆文件,而awk就是处理文件最小最快最灵活的工具,下面用类比wps公式的方式写一些用法:

先有个概念,公式操作的是xlsx表格,awk操作的是csv表格,csv最明显的好处是几百万上千万行处理起来没压力,而在功能上awk和表格公式能实现的操作并无太大差别

  • 筛选,类似filter

🔔

awk命令会逐行处理文本,文本像流水一样一行行流过awk命令,处理后生成结果

通过-F指定每一行按逗号分割成列,这里可以用正则分列

单引号里具体的处理,格式是 '条件{处理}',上图中只有条件$1=="2024/5/13",意思是第1列等于后面的字符串,可以改成匹配正则、行数大于等于等条件,按理说条件后面应该跟着大括号,里面是怎么处理,如果省略就是默认输出该行

wnl.csv是我下载的从1970到2100年的万年历csv表,每天一行,有农历节日等信息,这里当成例子

所以这一句的意思是,按逗号分列,第一列匹配时输出这一行

  • 统计,类似数据透视表

🔔

现在只看单引号里的程序部分,每个程序的格式是 '条件{处理}'

条件/^2024/是正则匹配的意思,这里匹配2024年5月,执行的处理是d[$2]++,意思是在字典d里,以第2列作为键,值自增1,大概可以理解成countif公式

条件END是指文件的所有行都处理过后执行,for循环遍历d里的键,打印出键和值

所以最终打印出了,2024年5月里每个星期日各有几个

  • 匹配,类似vlookup

📌

这里的FNR是当前文档的第几行,NR是所有文件里的第几行,它俩相等是指a.csv里的行,对这里的行的第1列,存到字典d里

next是指跳过后面的处理,类似if else里的else

后面就是判断之后的文件,第1列,是否存在于d里,如果存在就输出

所以,最终的意思是获取wnl匹配a.csv的行

  • 分表

👋

条件NR>1是跳过第一行的表头

print默认是输出当前行

>>类似重定向,输出到文件,文件名是第二列星期几加上后缀.txt

所以意思是,把wnl.csv按星期几分成七个分表

  • 去重或者输出重复的第几个

💡

先匹配2024年5月

然后if里的条件是,把第2列也就是星期几作为键,存入字典d,值自增1,当自增之后的值等于2时

最后输出第1第2列

所以最后的意思是输出2024年5月每个星期几出现的第2次日期,如果改成1,其实就是去重,只输出第一次出现的行

总的来说,当要处理百万行的csv时,awk是个快速处理的选择,思路大概就是,csv逐行流过awk程序,用-F参数指定分列用的符号或正则,匹配一定的条件,指定操作输出结果,在这里可用的主要方法,一是正则处理文本,二是关联数组(可以理解成字典)处理数据结构,配合上find等命令,在处理大量、超长的csv文件时,很方便灵活,省心省力

海南省
浏览 331
收藏
3
分享
3 +1
3
+1
全部评论 3
 
方盛
方盛

创作者俱乐部成员

我不是来打卡的
· 湖北省
1
回复
 
howard
打卡
· 云南省
1
回复
 
howard
打卡
· 云南省
回复