首页 >> 学习 >> Linux常用命令 >> awk
awk命令

本节重要性:★★★★☆    本节难度:★★★★★

awk是功能强大的模式分析与处理语言,其名字来源于该工具的作者Alfred Aho、Peter Weinberger和Brian Kernighan 姓氏的首个字母。我们前面学习的grep命令擅长模式查找,sed命令擅长内容编辑,而awk则擅长分析文本并按规定格式输出。awk本身是一门编程语言,有自己的控制结构和变量。

awk处理文本时类似于sed,也是一行一行的处理。一行称为一个记录,每行中由指定字符分割的一个字段称为

命令用途

文本模式扫描及处理

命令格式

awk [option] -f program-file file

awk [option] program-text file

常用选项

-f program-file	从program-file中读取程序脚本
-F fs		使用fs(field separator)作为输入文本域的分隔符

常见用法

awk的调用方式有3种:

1. 命令行方式
awk [-F fs] 'commands' input-file(s)
其中,commands是真正awk命令,[-F fs]是可选的。 input-file(s) 是待处理的文件。
文件的每一行中,由域分隔符分开的每一项称为一个域。在没有-F定义域分隔符的情况下,
默认的域分隔符是空格。

2. 命令行调用awk脚本文件方式(将所有的awk命令保存到一个单独文件,然后调用):
awk -f program-file input-file(s)
其中,-f选项加载program-file中的awk脚本,input-file(s)同上。

3. shell脚本方式
将awk命令保存到一个文件,给文件添加可执行权限,并在首行定义awk为命令解释器:
#!/bin/awk

我们首先来看一个最常见的awk应用:

[peter@ibi98 tr]$ ls -l
总用量 12
-rw-rw-r-- 1 peter peter 241  3月 16 10:44 demo_wc
-rw-rw-r-- 1 peter peter 708  3月 16 11:46 demo_wc_2
-rw-rw-r-- 1 peter peter 183  3月 16 17:00 demo_wc_3
[peter@ibi98 tr]$ ls -l |awk '{print $3}'

peter
peter
peter
[peter@ibi98 tr]$ ls -l |awk '{print $6}'

3月
3月
3月

上面的例子中,在“3月”前面有两个空格,由此可见awk默认把连续的空格作为一个域分隔符。第一行只有两个域,所以打印第三和第六个域时第一行都是空行。

如果域分隔符不是空格,可以用-F定义:

[peter@ibi98 xiezy]$ head -3 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[peter@ibi98 xiezy]$ head -3 /etc/passwd |awk -F ':' '{print $1}'
root
bin
daemon

awk命令格式为'[/pattern/]{action}'(方括号表示可以省略),即包括匹配模式和操作两部分,如果在一行中匹配到模式pattern,就对该行执行操作action;如果省略匹配模式部分,则对每一行都执行操作。我们还用上面的例子,加上模式匹配部分:

[peter@ibi98 xiezy]$ head -3 /etc/passwd |awk -F ':' '/root/{print $1}'
root

awk只输出包含模式“root”的行的第一个域的内容。

a是一种编程语言,其控制结构与C语言类似,如:

[peter@ibi98 awk]$ cat demo_awk
#Seq    Taxa    ChrNum  Species
1       plant   5       Arabidopsis thaliana
2       plant   12      Oryza sativa
3       animal  24      Homo sapiens
4       animal  20      Mus musculus
[peter@ibi98 awk]$ awk -F'\t' '{if($1 !~ /^#/ && $3>10) {print $1,$3,$4}}' demo_awk
2 12 Oryza sativa
3 24 Homo sapiens
4 20 Mus musculus

awk判断如果不是注释行(行首有#)且染色体数大于10,就输出序号、染色体数和物种名。

awk有一些内置变量,可以不用定义直接使用。awk的内置变量有:

ARGC		命令行参数个数
ARGV		命令行参数排列
ENVIRON		支持队列中系统环境变量的使用
FILENAME	awk浏览的文件名
FNR		浏览文件的记录数
FS		设置输入域分隔符,等价于命令行 -F选项
NF		浏览记录的域的个数
NR		已读的记录数
OFS		输出域分隔符
ORS		输出记录分隔符
RS		控制记录分隔符

下面的例子直接使用内置变量,NR是记录的序号,OFS定义输出的域的分隔符为制表符:

[peter@ibi98 awk]$ last -10 |awk '{OFS="\t";print NR,$1,$3}' |grep 'wang'
7       wangling        172.22.42.84
9       wangling        172.22.42.84

注意上面例子中awk命令外层是单引号,内层只能用双引号,再用单引号配对就会出错。

awk还经常用来选择和调整列的位置,用来为数据库的表准备数据:

[peter@ibi98 awk]$ cat demo_awk
#Seq    Taxa    ChrNum  Species
1       plant   5       Arabidopsis thaliana
2       plant   12      Oryza sativa
3       animal  24      Homo sapiens
4       animal  20      Mus musculus
[peter@ibi98 awk]$ cat demo_awk |grep -v "^#" |awk -F'\t' '{OFS="\t";print $1,$4,$3}'
1       Arabidopsis thaliana    5
2       Oryza sativa    12
3       Homo sapiens    24
4       Mus musculus    20

与前面的例子不同,该例中先用grep命令过滤掉注释行(Linux完成同一任务有多种方法,如果一个命令完成不了的,可以考虑该命令的选项是否提供该功能,如果还不行,再将不同的命令用管道组合起来,就可以完成大多数文本处理任务),再用awk处理。awk选择性输出4个字段(域)中的3个,并且将原来第4个字段调整到原来第3个字段前面。

<<上一节  下一节>>