awk入门与进阶part1—快速入门

awk入门与进阶part1—快速入门

awk 的结构

由一个单独的模式–动作语句(pattern-action statement) 组成。

pattern{ action }

awk的运行方式

awk 的基本操作是在由输入行组成的序列中,陆续地扫描每一行,搜索可以被模式匹配(match) 的行。每一个输入行轮流被每一个模式测试。每匹配一个模式,对应的动作(可能包含多个步骤) 就会执行。然后下一行被读取,匹配重新开始。这个过程会一起持续到所有的输入被读取完毕为止。

执行awk方式

  • awk+执行语句+文件

awk 'program' input files

  • awk+执行语句

在命令行上省略输入文件,在这种情况下, awk会将program应用到接下来在终端输入的内容,直到键入文件结束标志ctrl-d。

  • awk+脚本

awk -f progfile optional list of files

入门应知

输出

awk 从输入中每次读取一行,将行分解为一个个的字段(默认将字段看作是非空白字符组成的序列)。当前输入行的第一个字段叫作\$1,第二个是\$2,依次类推。一整行记为$0。每行的字段数有可能不同。

print 打印当前输出行,\$0 表示整行,\$1 表示第一个字段。在print 语句中由逗号分隔的表达式, 在输出时默认用一个空格符分隔。Awk 计算当前输入行的字段数量,并将它存储在一个内建的变量中,这个变量叫作NF。\$NF表示打印最后一个字段。

用字段的值进行计算,并将计算得到的结果放在输出语句中。如{print $1*$2}

另一个内建变量NR,这个变量计算到目前为止,读取到的行的数量。我们可以使用NR来表示行号。添加行号写法{ print NR, $0 }。添加文本,引号包围的文本会和字段和运算结果一起输出。

修改输出格式可以试用printif。使用格式printf(format, value1, value2, ..。, valuen) format 是一个字符串,包含按字面打印的文本, 中间包括格式说明符, 格式说明符用于说明如何打印值。一个格式说明符是一个%,后面跟着几个字符控制一个value 的输出格式。第一个格式说明符说明value1 的输出格式,第二个格式说明符说明value2 的输出格式,依次类推。使用printf 不会自动产生空格符或换行符必须自己添加\n。

选择

通过比较和计算或者文本可以选择输出感兴趣的行。

$1 >= 5
$1+$3 > 10
$1=="chr1"

结合逻辑运算符进行组合选择。

|| or; && and; ! not

数据验证

真实的数据总是存在错误,检查数据是否具有合理的值,格式是否正确,通常称作数据验证(data validation),数据验证的本质是否定,也就是说打印出可以的行。比如想验证是不是每一行都有4列,即可以使用NF != 4 {print $0}

BEGIN END

特殊的模式BEGIN 在第一个输入文件的第一行之前被匹配,END 在最后一个输入文件的最后一行被处理之后匹配。

计算

#计数:
awk '$2>1{num=num +1}END{print num}' awk.txt
#总数
awk 'END{print NR}' awk.txt
#平均数
awk '{sum=sum + $2}END{print sum/NR}' awk.txt
# 输出最大值(变量可以是字符串)
awk '$2 > max { max = $2; maxid = $1 }END { print max, maxid }' awk.txt
# 字符串拼接
awk '{id = id $1 " " }END { print id }' awk.txt
#字符个数 length
awk '{ print $3,length($3) }' awk.txt

流程控制

if-else

awk '
{ n = $2; id =$1 }
END { if (n > 333)
print n,id
else print "< 333"
}' awk.txt

for:大多数循环都包括初始化, 测试, 增值, 而for 语句将这三者压缩成一行。

awk '
{ for(i=1;i<= NR; i=i+1)
print i,$2' awk.txt

while:while 含有一个条件判断与一个循环体. 当条件为真时, 循环体执行.

awk '{ i = 1
while (i <= NR) {
print i, $1
i = i + 1
}
}' awk.txt

while 后面被括号包围起来的表达式是条件判断;循环体是跟在条件判断后面的,被花括号包围起来的的两条语句。

数组

Awk 提供了数组用来存储一组相关的值。

#逆序显示
awk'{ line[NR] = $0 } # remember each input line
END { i = NR # print lines in reverse order
while (i > 0) {
print line[i]
i = i - 1
}
}' awk.txt

awk'
{ line[NR] = $0 } # remember each input line
END { for (i = NR; i > 0; i = i - 1)
print line[i]
}'

awk常用一行命令

#1. 输入行的总行数
END { print NR }
#2. 打印第10 行
NR == 10
#3. 打印每一个输入行的最后一个字段
{ print $NF }
#4. 打印最后一行的最后一个字段
{ field = $NF }
END { print field }
#5. 打印字段数多于4 个的输入行
NF > 4
#6. 打印最后一个字段值大于4 的输入行
$NF > 4
#7. 打印所有输入行的字段数的总和
{ nf = nf + NF }
END { print nf }
#8. 打印包含Beth 的行的数量
/Beth/ { nlines = nlines + 1 }
END { print nlines }
#9. 打印具有最大值的第一个字段, 以及包含它的行(假设$1 总是正的)
$1 > max { max = $1; maxline = $0 }
END { print max, maxline }
#10. 打印至少包含一个字段的行
NF > 0
#11. 打印长度超过80 个字符的行
length($0) > 80
#12. 在每一行的前面加上它的字段数
{ print NF, $0 }
#13. 打印每一行的第1 与第2 个字段, 但顺序相反
{ print $2, $1 }
#14. 交换每一行的第1 与第2 个字段, 并打印该行
{ temp = $1; $1 = $2; $2 = temp; print }
#15. 将每一行的第一个字段用行号代替
{ $1 = NR; print }
#16. 打印删除了第2 个字段后的行
{ $2 = ""; print }
#17. 将每一行的字段按逆序打印
{ for (i = NF; i > 0; i = i - 1) printf("%s ", $i)
printf("\n")
}
#18. 打印每一行的所有字段值之和D
{ sum = 0
for (i = 1; i <= NF; i = i + 1) sum = sum + $i
print sum
}
#19. 将所有行的所有字段值累加起来
{ for (i = 1; i <= NF; i = i + 1) sum = sum + $i }
END { print sum }
#20. 将每一行的每一个字段用它的绝对值替换
{ for (i = 1; i <= NF; i = i + 1) if ($i < 0) $i = -$i
print
}

本文作者:思考问题的熊

版权声明:本博客所有文章除特别声明外,均采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。

# linux
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×