处理流程
当使用 awk 命令处理一个或者多个文件时,它会依次读取文件的每一行内容,然后对其进行处理,awk 命令默认从 stdio 标准输入获取文件内容,awk 使用一对单引号来表示一些可执行的脚本代码,在可执行脚本代码里面,使用一对花括号来表示一段可执行代码块,可以同时存在多个代码块。awk 的每个花括号内同时可以有多个指令,每一个指令用分号分隔,awk 其实就是一个脚本编程语言。
格式: awk ‘condition action’ filename
1
| awk -F '[|:;]' '{if ($1 > "m") print $1; else print "---"}' /etc/passwd
|
脚本化:
1 2 3 4 5 6
| #! /bin/awk -f BEGIN {print "begin to awk\n"} $s ~ /beijing/ END { print "end of awk" }
# xxx.awk xxx.data
|
内置变量
变量 |
含义 |
$0 |
行内容 |
$1 |
第一列字段 |
NF |
当前行有多少个字段 |
$NF |
最后一个字段 |
NR |
当前处理的是第几行 |
FILENAME |
当前文件名 |
FS |
字段分隔符,默认是空格和制表符。 |
RS |
行分隔符,用于分割每一行,默认是换行符。 |
OFS |
输出字段的分隔符,用于打印时分隔字段,默认为空格。 |
ORS |
输出记录的分隔符,用于打印时分隔记录,默认为换行符。 |
OFMT |
数字输出的格式,默认为%.6g。 |
内置函数
func |
含义 |
tolower() |
字符转为小写 |
length() |
返回字符串长度 |
substr() |
返回子字符串 |
sin() |
正弦 |
cos() |
余弦 |
sqrt() |
平方根 |
rand() |
随机数 |
组合使用
使用 awk 过滤 history 输出,找到最常用的命令
1 2 3 4 5 6 7 8 9 10 11
| [root@centos ~]# history | awk '{a[$4]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head 267 ll 122 vim 118 cd 54 awk 34 man 28 g++ 23 rm 21 cat 16 mkdir 13 gcc
|
过滤文件中重复行
假设有一个文本,每一行都是一个 int 数值,想要计算这个文件每一行的和
1
| awk '{s+=$1} ENG {printf "%.0f", s}' /path/to/file
|
next
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| No Item_Name Price Quantity 1 Mangoes $3.45 5 2 Apples $2.45 25 3 Pineapples $4.45 55 4 Tomatoes $3.45 25 5 Onions $1.45 15 6 Bananas $3.45 30
awk '$4 <= 20 { printf "%s\t%s\n", $0,"*" ; } $4 > 20 { print $0 ;} ' food_list.txt
No Item_Name Price Quantity 1 Mangoes $3.45 5 * 2 Apples $2.45 25 3 Pineapples $4.45 55 4 Tomatoes $3.45 25 5 Onions $1.45 15 * 6 Bananas $3.45 30
|
当第一个表达式用{ printf “%s\t%s\n”, $0,”**” ; }命令进行标注的时候在同样的步骤第二个表达式也进行了判断这样就浪费了时间; 这个东西不是 if else; 而是都判断的,不判断后一个,可以
1
| awk '$4 <= 20 { printf "%s\t%s\n", $0,"*" ; next; } $4 > 20 { print $0 ;} ' food_list.txt
|
REF