总结awk中使用内置函数以及if-else、for循环等用法。
awk中除了一些内置函数之外,也可以与其他函数结合在一起使用实现一些复杂的用法。
1. awk中内置函数
函数 | 函数作用 | 用法 | 命令输出 |
---|---|---|---|
length($0) | 输出$0的长度 | echo "hello" | awk '{print length($0)}' |
5 |
substr(str,start,length) | 返回字符串中从start位置开始长度为length的子串 | echo "hello world" | awk '{print substr($0,7,5)}' |
world |
index(str,sub) | 返回str字符串中第一次出现子串sub的位置,如果没有匹配,返回0 | echo "hello" | awk '{print index($0,"world")}' |
7 |
split(str,arr,sep) | 将字符串按照分隔符sep分隔成数组arr | echo "1,2,3,4" | awk '{split($0,arr,",");print arr[3]}' |
3 |
gsub(regexp,replacement,str) | 用字符串replacement替换字符串str中所有匹配正则表达式regexp的子串 | echo "hello world" | awk '{gsub(/o/,"O",$0);print}' |
hellO wOrld |
six(x)、cos(x)、tan(x)、exp(x)、log(x)、sqrt(x) | 数学函数,计算正弦值、余弦值、正切值、指数函数、对数、平方根 | echo "3.1415926" | awk '{print sin($0)}' |
0.001592665 |
sstrftime(format,timestamp) | 将时间戳timestamp格式转换为指定的日期格式 | echo $(date +%s) | awk '{print strftime("%Y-%m-%d %H:%M:%S", $1)}' |
输出当前时间的日期格式2023-05-02 12:24:59 |
tolower($0)、toupper($0) | 将字符串转换为大/小写 | echo "hello world" | awk '{print toupper($0)}' |
HELLO WORLD |
2. awk中使用控制语句:if-else条件语句/for循环/while循环/do-while循环
if/else
条件语句:可以根据指定的条件执行不同的操作。1
awk '{if($1 > 10) {print "large"} else {print "small"}}' file.txt
上面的命令根据第一个字段的值输出 “large” 或 “small”。
for
循环:可以使用for
循环对指定的字段进行遍历。1
awk '{for(i=1; i<=NF; i++) {print $i}}' file.txt
上面的命令遍历每个字段并输出。
while
循环:可以使用while
循环对指定的条件进行迭代。1
awk '{i=1; while(i<=NF) {print $i; i++}}' file.txt
上面的命令使用
while
循环遍历每个字段并输出。do/while
循环:可以使用do/while
循环对指定的操作进行迭代,直到满足指定的条件为止。1
awk '{i=1; do {print $i; i++} while(i<=NF)}' file.txt
上面的命令使用
do/while
循环遍历每个字段并输出。
3. awk中使用数组
在 awk
中,数组是一种非常有用的数据结构,可以用于存储和处理文本数据。awk
中的数组是关联数组,也就是说,数组的下标可以是任意字符串或数字。
以下是 awk
中使用数组的示例:
声明和初始化数组:
1
awk 'BEGIN{arr["apple"]=1; arr["orange"]=2; arr["banana"]=3; print arr["apple"], arr["orange"], arr["banana"]}' file.txt
上面的命令中,声明了一个名为
arr
的数组,并初始化了三个元素,然后输出了这些元素的值。遍历数组:
1
awk 'BEGIN{arr["apple"]=1; arr["orange"]=2; arr["banana"]=3; for(i in arr) {print i, arr[i]}}' file.txt
上面的命令中,使用
for
循环遍历了arr
数组,并输出了数组中每个元素的下标和值。使用数组进行计数:
1
awk '{count[$1]++} END{for(i in count) {print i, count[i]}}' file.txt
上面的命令中,每次处理一行时,将第一个字段作为数组
count
的下标,并将对应的元素加 1。在处理完所有行后,使用for
循环遍历count
数组,并输出每个元素的下标和值,从而实现对每个值出现次数的计数。
以上是 awk
中使用数组的示例,数组在 awk
中的使用非常灵活,可以根据需要进行不同的操作。
4. awk分隔符
- 使用多个分隔符
awk默认使用空格或tab为分隔符,使用多个分隔符时,用-F参数指定1
awk -F '[,;]' '{print $1,$2,$3}' file.txt
- 自定义输出分隔符
使用OFS变量定义自定义输出分隔符:1
awk 'BEGIN{OFS=","} {print $1,$2,$3}' file.txt
- 使用正则表达式
使用正则表达式匹配文本:输出文件中包含pattern的行的第一列和第二列。1
awk '/pattern/{print $1,$2}' file.txt
5. awk高级用法实例
有一个test文件内容如下:
1 | cat test |
利用awk根据第一列值的不同进行分组,求第二列在相应组别中所占的比例。
1 | awk 'BEGIN{ |
结果:
1 | 1 3 12 0.25 |
需要将文件遍历两遍,第一遍根据不同的分组计算不同组别的总和(求不同分组的和必然要将文件每一行都遍历一遍),第二遍求每一行相应数据所占的比例。所以需要将该文件遍历两遍,awk中将文件遍历两遍,可以使用getline函数。geline类似于python中的readline,一行一行地读取数据,最后遍历完之后将求得的和存入数组,然后关闭文件再重新进行第二遍的读取。
第一列是字符串时也适用:
1 | cat test |
结果如下:
1 | a 3 7 0.428571 |