Linux字段处理之awk实例详解

来源:互联网 发布:淘宝小米没有碎屏险 编辑:程序博客网 时间:2024/05/17 07:10

使用awk重新编排字段

模式与操作

 

①基本模式为:

awk 'program' [ file...]

awk读取命令行所指定的各个文件(若无,则从标准输入),一次读取一条记录(行)

再针对每一行,引用程序所指定的命令。

 

awk程序的基本架构为

pattern {action}

pattern {action}

...

patternaction均可省略,佘略pattern,则会对每一条记录执行action

省略action泽东等同于{print},将显示整条记录。

 

③大部分单命令行程序格式如下:

... | awk '{ print some-stuff }' | ...

对每条记录而言,awk会测试程序里的每个pattern,若模式为真,则awk便执行action内的程序代码。

 

使用方法

awk '{pattern + action}' {filenames}

其中 pattern表示 AWK 在数据中查找的内容,而 action是在找到匹配内容时所执行的一系列命令。

花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。

pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。

完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

 

调用awk

.命令行方式

awk [-F field-separator] 'commands' input-file(s)

其中,commands是真正awk命令,[-F域分隔符]是可选的。 input-file(s)是待处理的文件。

awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

 

.shell脚本方式

将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。

相当于shell脚本首行的:#!/bin/sh

可以换成:#!/bin/awk

 

.将所有的awk命令插入一个单独文件,然后调用:

awk -f awk-script-file input-file(s)

其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。

 

实例1:打印字段

[gz_fieldyang@test ~]$ last -n 3

sninf_ke pts/2       172.20.204.18   Mon Mar 7 16:49  still logged in  

gz_field pts/1       172.23.33.204   Mon Mar 7 16:47  still logged in  

sninf_to pts/3       172.20.204.19   Mon Mar 7 16:39 - 16:44 (00:05)   

 

wtmp begins Wed Jan 27 10:14:25 2016

[gz_fieldyang@test ~]$ last -n 3|awk '{print $1}'   

sninf_ke                                        #打印第一个字段,(未指定pattern

gz_field

sninf_to

 

wtmp

[gz_fieldyang@ test ~]$ last -n 3|awk '{print $2,$5}'

pts/2 Mar                                       #打印第2与第5个字段,(未指定pattern

pts/1 Mar

pts/3 Mar

 

begins 27

[gz_fieldyang@ test ~]$ last -n 3|awk '{print $1,$NF}'

sninf_ke in                                      #打印第一个与最后一个字段,(未指定pattern

gz_field in

sninf_to (00:05)

 

wtmp 2016

[gz_fieldyang@ test ~]$ last -n 3|awk 'NF>0 {print $0}'  

           #打印非空行(指定patternaction

sninf_ke pts/2       172.20.204.18   Mon Mar 7 16:49  still logged in  

gz_field pts/1       172.23.33.204   Mon Mar 7 16:47  still logged in  

sninf_to pts/3       172.20.204.19   Mon Mar 7 16:39 - 16:44 (00:05)   

wtmp begins Wed Jan 27 10:14:25 2016

# $0为比较特别的字段,表示打印整条记录。

[gz_fieldyang@ test ~]$ last -n 3|awk 'NF>0'          

         #打印非空行(未指定action,则默认为打印)

sninf_ke pts/2       172.20.204.18   Mon Mar 7 16:49  still logged in  

gz_field pts/1       172.23.33.204   Mon Mar 7 16:47  still logged in  

sninf_to pts/3       172.20.204.19   Mon Mar 7 16:39 - 16:44 (00:05)   

wtmp begins Wed Jan 27 10:14:25 2016

[gz_fieldyang@test ~]$

 

实例2:设置字段分隔字符 (awk -F...)

 

[gz_fieldyang@ test ~]$ last -n 2|awk -F/ 'NF>0  {print $1}'

sninf_ke pts

gz_field pts

wtmp begins Wed Jan 27 10:14:25 2016

[gz_fieldyang@ test ~]$ last -n 2|awk -F/ 'NF>0  {print $2}'

2       172.20.204.18   Mon Mar 7 16:49  still logged in  

1       172.23.33.204   Mon Mar 7 16:47  still logged in  

 

[gz_fieldyang@test ~]$

[gz_fieldyang@test ~]$ awk -F: '{print $1,$5}' /etc/passwd #处理/etc/paswwd

root root                                #管理账号

...

gz_kinma                              #实际用户

gz_fieldyang

...

 

实例3:改变字段分隔字符 (awk -v 'OFS=...')

[gz_fieldyang@test ~]$ awk -F: -v 'OFS=**' '{print $1,$5,$7}' /etc/passwd   

root**root**/bin/bash

...

sninf_tonyhung****/bin/bash

gz_kinma****/bin/bash

gz_fieldyang****/bin/bash

....

 

实例4:打印行

[gz_fieldyang@test ~]$ awk -F: '{print "User",$1,"Shell is",$7}' /etc/passwd   

User root Shell is /bin/bash                            #awkprint语句自动提供最后的换行字符,

User bin Shell is /sbin/nologin                       #各参数间使用逗号隔开

...

User gz_kinma Shell is /bin/bash

User gz_fieldyang Shell is /bin/bash

...

使用printf实现相同功能

[gz_fieldyang@test ~]$ awk -F: '{printf "User %s Shell is %s\n", $1,$7}' /etc/passwd

User root Shell is /bin/bash

User bin Shell is /sbin/nologin

...

User gz_kinma Shell is /bin/bash

User gz_fieldyang Shell is /bin/bash

...

注意:使用printf语句,最后需要使用\n转义序列使自己提供换行

 

起始与清除

BEGINEND这两个特殊的”模式“,提供awk程序的起始(startup)和清除(cleanup)操作

常见于大型awk程序中,且通常写在个别文件中,而不是在命令行上

 

BEGIN   {起始操作程序代码(startup code)}

pattern1 {action1}

pattern2 {action2}

END     {清除操作程序代码(cleanup code)}

 

BEGINEND代码块是可选的,习惯上(非必须)用于awk程序开头结尾,可以同时存在数个BEGINEND语句块,

awk会按顺序执行:所有的BEGIN语句块都应放在起始处,而所有的END语句块放在结尾处

 

简单实例:

[gz_fieldyang@ test ~]$ awk 'BEGIN {FS=":" ;OFS="**"}         #使用BEGIN设置变量

> {print $1,$3,$5}' /etc/passwd                                                   #被应用的程序继续第二行

root**0**root

bin**1**bin

....

gz_kinma**857**                                                                          #输出,如前。

gz_fieldyang**859**

0 0
原创粉丝点击