awk文本处理示例

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
踏浪 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!