百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

awk学习笔记

toyiye 2024-06-21 12:38 11 浏览 0 评论

一、awk简介

awk是一个文本分析工具,也可以认为是一种处理文本的语言,之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

awk处理的数据来源可以是标准输入、一个或多个文件。支持内置变量、内置函数、运算符、数组、逻辑判断、循环、自定义函数等功能。

二、运行原理

1、命令行执行语法:

awk [选项参数] 'script' var=value file(s) (命令行直接写awk程序,即 script)

或者 :awk [选项参数] -f scriptfile var=value file(s) (awk程序写在脚本文件中,即 scriptfile)

其中,file(s)表示输入文本文件可以是多个文件,在程序中可以通过内置变量FILENAME获取当前文件名

主要的选项参数包括:

-f scriptfile-file :从脚本文件中读取awk程序代码

-F fs :指定输入文本的分隔符,默认空格和制表符

-v var=val:自定义变量赋值

2、脚本程序运行原理:

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

首先执行开始块: BEGIN {commands} 内的语句块,注意这只会执行一次,经常用于变量初始化、打印表头信息等,在读入数据前就被执行。这里 BEGIN是固定关键字;

其次执行主体块:主体块没有关键字。pattern{ commands }可以有多个,如pattern1{command1} pattern2{command2} 。。。,awk是以行为单位处理的,每读取一行,就顺序执行每一个pattern{commands}。 可以理解成一个for循环,每一行文本是for循环的变量,一个个pattern{commands} 是顺序执行的循环体。

pattern 部分可以是正则表达式、关系表达式或者模式匹配表达式,用来筛选特定文本行,如果pattern为空,则全部选取。

commands 可以是变量或数组赋值、内置函数或自定义函数执行、输出命令、控制流语句

最后执行 END{ commands } ,也是只会执行一次,在所有行处理完后执行,通常用于打印一些统计结果

三个部分根据具体情况,都是可有可无。

例如,文本文件 sample.txt 内容如下:

1001,bob,60,500,男

1002,adam,58,300,女

1003,jim,65,700,女

1004,tomas,53,100,男

执行以下命令:

#只输出姓名、年龄两列
awk -F',' '{print $2,$3}' sample.txt
bob 60
adam 58
jim 65
tomas 53

#输出年龄大于等于60的所有数据
awk -F',' '$3>=60{print}' sample.txt      
1001,bob,60,500,男
1003,jim,65,700,女

#输出姓名中包含字母a的所有数据,并规范格式输出
awk -F',' '$2~/a/{printf "%-7s %-7s %-7s %-7s %-7s\n",$1,$2,$3,$4,$5}' sample.txt
1002    adam    58      300     女      
1004    tomas   53      100     男

#格式化输出特定几列(姓名、年龄、金额),并计算输出总金额
awk -F',' 'BEGIN{sum=0;printf "%-7s %-7s %-7s\n","id","age","money"}{sum+=$4;printf "%-7s %-7s %-7s\n",$2,$3,$4}END{print "total money:",sum}' sample.txt 
id      age     money  
bob     60      500    
adam    58      300    
jim     65      700    
tomas   53      100    
total money: 1600

三、运算符

= += -= *= /= %= ^= **= 赋值

?: C条件表达式

|| 逻辑或

&& 逻辑与

~ 和 !~ 匹配正则表达式和不匹配正则表达式

< <= > >= != == 关系运算符

空格 连接

+ - 加,减

* / % 乘,除与求余

+ - ! 一元加,减和逻辑非

^ *** 求幂

++ -- 增加或减少,作为前缀或后缀

$ 字段引用

in 数组成员

四、数组

awk支持关联数组

赋值:array_name[index]=value

取值:array_name[index]

删值:delete array_name[index]

模拟多维数组(awk本身不支持多维数组,使用字符串key模拟):array_name["0,0"]=value00 array_name["0,1"]=value01

示例:

#数组赋值、取值
awk 'BEGIN {teams["arsenal"]=4;teams["m_city"]=1;print teams["arsenal"]}'
4
#数组删除元素
awk 'BEGIN {teams["arsenal"]=4;teams["m_city"]=1;delete teams["arsenal"];print "m_city:"teams["m_city"]"\n""arsenal:"teams["arsenal"]}'  
m_city:1
arsenal:
#模拟多维数组
awk 'BEGIN {arr["0,0"]=100;arr["0,1"]=200;arr["1,0"]=300;arr["1,1"]=400;print arr["0,0"],arr["0,1"] "\n" arr["1,0"],arr["1,1"]}'
100 200
300 400

五、控制流语句

类似C语言的语法

判断:支持 if(){}、if(){} else{}、if(){} else if(){} else{}

循环:支持 for 、while ,关键字 break(退出循环)、continue(结束本次循环)、exit(结束程序) 控制退出时机

#计算输出每种金额的人数
awk -F',' '{arr[$4]++}END{for(i in arr)print i,arr[i]}' sample.txt sample_2.txt 
300 2
600 1
100 1
700 2
500 2

六、内置变量

$n : 当前记录的第n个字段,字段间由FS分隔

$0 : 完整的输入记录

ARGC: 命令行参数的数目

ARGIND: 命令行中当前文件的位置(从0开始算)

ARGV: 包含命令行参数的数组

CONVFMT: 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组

ERRNO: 最后一个系统错误的描述

FIELDWIDTHS: 字段宽度列表(用空格键分隔)

FILENAME: 当前文件名

FNR: 各文件分别计数的行号

FS: 字段分隔符(默认是任何空格)

IGNORECASE: 如果为真,则进行忽略大小写的匹配

NF: 一条记录的字段的数目

NR: 已经读出的记录数,就是行号,从1开始

OFMT: 数字的输出格式(默认值是%.6g)

OFS: 输出字段分隔符,默认值与输入字段分隔符一致。

ORS: 输出记录分隔符(默认值是一个换行符)

RLENGTH: 由match函数所匹配的字符串的长度

RS: 记录分隔符(默认是一个换行符)

RSTART: 由match函数所匹配的字符串的第一个位置

SUBSEP: 数组下标分隔符(默认值是/034)

#两个文件顺序输出,并在每一行结尾新增一列,标明来源文件名
awk -F',' 'BEGIN{OFS=","}{print $0,FILENAME}' sample.txt sample_2.txt 
1001,bob,60,500,男,sample.txt
1002,adam,58,300,女,sample.txt
1003,jim,65,700,女,sample.txt
1004,tomas,53,100,男,sample.txt
1005,john,61,500,男,sample_2.txt
1006,kody,49,300,女,sample_2.txt
1007,amy,71,700,女,sample_2.txt
1008,saka,70,600,男,sample_2.txt

七、内置函数

主要分为以下几种:

算数函数(atan2、cos、sin、exp、log、sqrt、int、rand、srand)

字符串函数(gsub、sub、substr、index、length、substr、match、split、tolower、toupper、sprintf、strtonum)

时间函数(mktime、strftime、systime)

位操作函数(and、compl、lshift、rshift、or、xor)

其它函数(close、delete、exit、flush、getline、next、nextfile、return、system)

#将姓名列大写输出
awk -F',' '{print toupper($2)}' sample.txt
BOB
ADAM
JIM
TOMAS

八、自定义函数

awk支持自定义函数,以提高代码复用性

语法格式:function name(arg1, arg2, ...) {...}

#自定义取最小值函数
awk 'function find_min(n1,n2){if(n1<n2) return n1;return n2} BEGIN{result=find_min(2,3);print "mininum=",result}'
2

九、其他例子

1、按不同列排序,如果同一列的值相同,保留另一列的值最大的那个记录

比如用户登录记录:

50025 20220101

50025 20220109

50026 20220124

50026 20220101

执行结果为:

50025 20220109

50026 20220124

脚本如下:

#其中 awk '!a[$1]++' 表示保留第一次出现过的记录
cat login_log.txt | sort -k1b,1 -k2r | awk '!a[$1]++'

2、行列转换

原始文件:

name age

tom 21

lily 20

jim 19

执行结果为:

name tom lily jim

age 21 20 19

脚本如下:

{
    for(i=1;i<=NF;i++){
        if(!(i in arr)){
            arr[i]=$i
        }else{
            arr[i] = arr[i]" "$i
        }
    }
}
END {
    for(i=1;i<=NF;i++){
        print arr[i]
    }   
}

3、批量重命名文件

find . -name '*.txt' | awk 'BEGIN{ a=0 }{ printf "mv %s name%01d.txt\n", $0, a++ }' | bash

4、打印九九乘法表

seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'

5、文本格式修改

原文本:

VFUNC 4718 2020 770951 3187699

0 2052

25 2300

50 2512

100 2930

VFUNC 4718 2040 770979 3187750

0 2056

25 2302

50 2530

100 2950

修改后文本:

770951 3187699 0 2052

770951 3187699 25 2300

770951 3187699 50 2512

770951 3187699 100 2930

770979 3187750 0 2056

770979 3187750 25 2302

770979 3187750 50 2530

770979 3187750 100 2950

脚本如下:

NR==1 {
     f4=$4
     f5=$5
}

NR>1 && NR<6{
     print f4 " " f5 " " $0
}

NR==6 {
    f64=$4
    f65=$5
}

NR>6 && NR<11{
    print f64 " " f65 " " $0
}

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码