awk命令提供了用于文本处理的脚本语言。使用awk脚本语言,您可以进行以下操作
- 定义变量
- 使用字符串和算术运算符
- 使用控制流和循环
- 生成格式化报告
实际上,您可以处理包含数百万行的日志文件,以输出可读报告。
awk 选项
awk 命令使用方法如下
1 | $ awk options program file |
awk 能设置以下参数:
-F fs 指定文件分隔符.
-f file 指定包含awk脚本的文件.
-v var=value 声明一个变量.
读取awk脚本
定义一个awk脚本, 使用单引号包围的花括号标记
1 | $ awk '{print "Welcome to awk command tutorial "}' |
使用变量
使用awk, 你能处理文本文件. awk 为每一个数据字段赋值了变量:
- $0 表示整行
- $1 表示第一个字段
- $2 表示第二个字段
- $n 表示第N个字段.
像空格或制表符这样的空白字符是awk中字段之间的默认分隔符
$ awk '{print $1}' myfile
D:\>cat myfile
This is a test.
This is the second test.
This is the thrid test.
This is the fourth test.
D:\>awk '{print $1}' myfile
This
This
This
This
上面的例子打印每行的第一个单词
有时某些文件中的分隔符不是空格,也不是制表符,而是其他内容。您可以使用-F选项指定它
1 | $ awk -F: '{print $1}' /etc/passwd |
此命令打印passwd文件中的第一个字段。我们使用冒号作为分隔符,因为passwd文件使用它
使用多个命令
要运行多个命令,请使用这样的分号分隔它们
1 | $ echo "Hello Tom" | awk '{$2="Adam"; print $0}' |
第一个命令使$2字段等于Adam。第二个命令打印整行
从文件中读取脚本
您可以在文件中键入awk脚本,并使用-f选项指定该文件。
这里我们从/etc/passwd打印用户名和他的路径,当然分隔符是用大写字母-F指定的
awk脚本testfile如下
{
text = $1 " home at " $6
print text
}
$ awk -F: -f testfile /etc/passwd
awk预处理
如果您需要为结果创建标题。您可以使用BEGIN关键字来实现此目的。它在处理数据之前运行
$ awk 'BEGIN {print "Report Title"}'
$ awk 'BEGIN {print "The File Contents:"} {print $0}' myfile
awk后处理
在处理数据后运行脚本,使用END关键字:
$ awk 'BEGIN {print "The File Contents:"} {print $0} END {print "File footer"}' myfile
这很有用,您可以使用它来添加页脚
让我们将它们组合在一个脚本文件中:
BEGIN {
print "Users and thier corresponding home"
print " UserName \t HomePath"
print "___________ \t __________"
FS=":"
}
{
print $1 " \t " $6
}
END {
print "The end"
}
首先,使用BEGIN关键字创建顶部。然后我们定义FS并在末尾打印页脚
$ awk -f myscript /etc/passwd
内置变量
变量$1,$2 ,$3用于提取数据字段,我们还处理字段分隔符FS。
但这些不是唯一的变量,还有更多的内置变量。
以下列表显示了一些内置变量:
- FIELDWIDTHS 指定字段宽度.
- RS 指定记录分隔符.
- FS 指定字段分隔符.
- OFS 指定输出分隔符.
- ORS 指定输出分隔符.
OFS 默认值是空格, 你能指定它
$ awk 'BEGIN{FS=":"; OFS="-"} {print $1,$6,$7}' /etc/passwd
有时候,字段分布没有指定的分隔符.FIELDWIDTHS 变量能处理这种问题
例如:有以下内容
1235.96521
927-8.3652
36257.8157
$ awk 'BEGIN{FIELDWIDTHS="3 4 3"}{print $1,$2,$3}' testfile
D:\>awk 'BEGIN{FIELDWIDTHS="3 4 3"}{print $1,$2,$3}' myfile
123 5.96 521
927 -8.3 652
362 57.8 157
输出字段为每行3个,并且每个字段长度基于 FIELDWIDTH 的设置
更多变量
- ARGC 获取传递参数的数量
- ARGV 获取命令行参数
- ENVIRON shell 环境变量数组
- FILENAME awk处理的文件名
- NF 每行处理的字段数量
- NR 记录总数
- FNR 处理的记录
- IGNORECASE 忽略字符大小写
$ awk 'BEGIN{print ARGC,ARGV[1]}' myfile
2 myfile
获取shell环境变量:
$ awk '
BEGIN{
print ENVIRON["PATH"]
}'
你可以使用 bash 变量 而不是 ENVIRON 变量:
$ echo | awk -v home=$HOME '{print "My home is " home}'
NF变量指定记录最后一个字段
$ awk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd
NF 变量能被使用作为一个数据字段: $NF
用户自定义变量
你能在shell文件中定义变量如下
$ awk '
BEGIN{
test="Welcome to LikeGeeks website"
print test
}'
结构化的命令
if条件语句
testfile 包含如下内容:
10
15
6
33
45
$ awk '{if ($1 > 30) print $1}' testfile
你能用花括号如果想执行更多语句
$ awk '{
if ($1 > 30)
{
x = $1 * 3
print x
}
}' testfile
While 循环
124 127 130
112 142 135
175 158 245
118 231 147
$ awk '{
sum = 0
i = 1
while (i < 5)
{
sum += $i
i++
}
average = sum / 3
print "Average:",average
}' testfile
for循环
$ awk '{
total = 0
for (var = 1; var < 5; var++)
{
total += $var
}
avg = total / 3
print "Average:",avg
}' testfile
格式化输出
printf 命令允许你打印指定格式的输出
指定格式如下:
%[modifier]control-letter
printf可指定的格式有:
- c 打印数字作为字符串.
- d 打印整数值.
- e 打印科学计数值.
- f 打印浮点数.
- o 打印八进制值.
- s 打印文本字符.
$ awk 'BEGIN{
x = 100 * 100
printf "The result is: %e\n", x
}'
内置方法
数学方法
sin(x) | cos(x) | sqrt(x) | exp(x) | log(x) | rand()
$ awk 'BEGIN{x=exp(5); print x}'
字符串方法
$ awk 'BEGIN{x = "likegeeks"; print toupper(x)}'
用户自定义方法
$ awk '
function myfunc()
{
printf "The user %s has home path at %s\n", $1,$6
}
BEGIN{FS=":"}
{
myfunc()
}' /etc/passwd