Linux 常用命令 AWK

2014-03-19 linux command

AWK 是一种程序语言,对文档资料的处理具有很强的功能,擅长从格式化报文或一个大的文本文件中抽取数据,会将一行文字按分隔符分为多个域,然后进行处理。

这里简单介绍其常用的方法。

简介

----- 通常使用的是单引号,如果是双引号,那么示例如下
$ ls -l $dir | awk "/$base\$/ { print \$1 \$3 \$4 }"
$ p=`ls -l $dir | awk "/$base\$/ { print \\\$1 \\\$3 \\\$4 }"`

----- 分割passwd文件
$ awk -F : '$1=="root" {print $0}' /etc/passwd

常用语法

if else

awk '{if ($1==1) print "A"; else if ($1==2) print "B"; else print "C"}'

注意,每个语句后面需要使用 ; 进行分割。

与 Shell 交互

在写 Shell 脚本时,经常会使用到 awk 程序,此时可能会需要两者之间相互调用。

Awk 使用 Shell 变量

主要有如下的几种方法。

方法 <1>

var="abc"
awk 'BEGIN{print "'$var'"}'

这种写法其实际是双括号变为单括号的常量,然后传递给了 awk 。

方法 <2>

var="this a test"
awk 'BEGIN{print "'"$var"'"}'

如果变量的值中包含空格,为了使 shell 不把空格作为分隔符,则应使用这一方法。

方法 <3>

var="this a test"; export var;
awk 'BEGIN{print ENVIRON["var"]}'

也就是使用环境变量进行传递。

方法 <4>

var="this a test"
awk -v awkVar="$var" 'BEGIN{print awkVar}'

{% endhighlight %}

也就是使用 -v 选项,如果变量不多时,建议使用这一方式。

Shell 使用 Awk 变量

其方法无非是用 awk (sed perl 也一样) 输出若干条 shell 命令,然后再用 shell 去执行这些命令。

eval $(awk 'BEGIN{print "var1='str1';var2='str2'"}')
eval $(awk '{printf("var1=%s; var2=%s; var3=%s;",$1,$2,$3)}' abc.txt)
echo "var1=$var1 ----- var2=$var2"

示例

计算进程 CPU 使用率

#!/bin/bash

BOOTIME=`awk '{ print $1 }' /proc/uptime`
HERTZ=`getconf CLK_TCK`

if [[ ! "${BOOTIME}" =~ ^[0-9.]*$ ]]; then
        return 1
fi

if [[ ! "${HERTZ}" =~ ^[0-9]*$ ]]; then
        return 1
fi

CPUSAGE=`awk -v bootime="${BOOTIME}" -v hz="${HERTZ}" 'BEGIN{percent=0}; {  \
        tmp = bootime * hz - $22;                                           \
        if (tmp <=0) percent = 0; else percent = ($14 + $15) * 100 / tmp    \
        } END{print percent}' /proc/14945/stat`

echo $CPUSAGE

按列求和

可以使用 awk 命令计算文件中某一列的总和。

----- 对第二列求和
$ awk 'BEGIN{sum=0}{sum+=$2}END{print sum}' data.txt

----- 对满足开始为/foobar/的行求和
$ awk 'BEGIN{sum=0};/foobar/{sum+=$2};END{print sum}' data.txt

----- 另外比较完整的一个例子
$ awk -F ',' 'BEGIN{sum=0;count=0}{if ($(NF-11)==2 && $NF==0 && $3=="11" && $6~/TIME|ESTABLISHED/) \
     {sum +=$5; count++;} } END {print "sum="sum" count="count " avg="sum/count}'

$N 表示第 N 列,从 0 开始计算;$0 表示所有列;NF 表示 Number of Fields,也就是字段数,$NF 表示最后一个字段,$(NF-1) 表示倒数第二个字段。