TOC

Linux 文本处理:awk

awk 的文档写出来可能有一本很厚的书,里面甚至有一种内嵌的解释性编程语言在里面。但是我们普通人就把他当一个小工具,了解一下基础用法就好了,不用深入研究。它的基本功能是将字符串切割之后按照 $1 ... $n 来处理,$0 表示整个字符串(整行)。

基础示例

# 默认按空格和 Tab 分割
awk '{print $1}' /etc/hosts

# 指定分割,然后使用特殊变量
awk -F: '{print NR ". " $1 "\t" $NF}' /etc/passwd

特殊变量

  • FILENAME 文件名
  • NF 字段数
    • $NF 用来值最后一个字段
  • NR 行数
  • FNR 当前行数
  • FS 字段分隔符 FieldSep , 默认是空格和 Tab
  • OFS 字段分隔符 FieldSep (输出 Output), 默认是空格
  • RS 行分割符 RowSep , 默认是换行符
  • ORS 行分隔符 RowSep (输出 Output), 默认是换行符
  • OFMT 数字输出格式,默认 %.6g

函数

https://www.gnu.org/software/gawk/manual/html_node/Built_002din.html

文章中分成六类:数值函数,字符串函数,IO函数,时间函数,位运算函数,类型函数,多语言函数。
简单使用的话,可能用的多的应该是几个字符串函数:

  • length([string])
  • index(in, find)
  • tolower(string)
  • toupper(string)
  • substr(string, start [, length ])
  • split(string, array [, fieldsep [, seps ] ])

PS:数值性可以直接进行计算,够用了。

综合应用

分组统计

# for
awk '{c[$9]++}END{for(i in c){print i c[i]}}' action.log

# for,printf
awk '{c[$10]++}END{for(i in c){printf "%10d %10d\n",i,c[i]}}' action.log | sort -k2 -r

# if (还可以 else)
awk -F: '{if ($NF != "/sbin/nologin") print $1}' /etc/passwd

# 过滤:跳过第一行
awk -F, 'NR>1{print $1}' students.csv
# 过滤:奇数行
awk -F, 'NR%2==1{print $1}' students.csv
# 过滤:正则表达式
awk -F: '/home/{printf "%20s\t%20s\t%s\n",$1,$(NF-1),$0}' /etc/passwd

PS: end 指最后一行之后,before 指第一行之前

参考资料与拓展阅读