Linux文本处理三剑客——awk

文本处理三工具:grep,sed,awk

  • grep:文本过滤工具:pattern;
  • sed:行编辑器:模式空间、保持空间;
  • awk:报告生成器:格式化文本输出;

awk命令

awk的运行方式

  • (1)awk 命令行
  • (2)awk 程序文件
  • (3)awk 脚本

命令格式

awk [options] 'program' FILE ....
其中,program:PATTERN{ACTION STATEMENT}
        PATTERN:模式
        ACTION STATEMENT:动作语句,可以是由多个语句组成,各语句间使用分号分隔;

常用选项

-F:指明输入时用到的字段分隔符;
-v var=value:自定义变量;

awk工作过程

  • 一次性读取一行文本,然后根据输入分隔符(默认为空格字符)对文本进行切片;
  • 将文本切成n个片段,然后将每一片都赋予awk内部的一个变量进行保存,这些变量名为$1、$2、$3......$n;
  • awk可以对上述片段进行单独处理,比如:显示某一段、特定段、甚至可以对某些片段进行额外的加工处理,比如计数、运算等。

1.awk的输出命令之一:print

用法:

print item1,item2,....
item:字符串,用引号引用;
       print "hello","world"
变量:显示变量的值,可以直接使用变量的名进行引用,不需要加$;
       print name
数值:无需加引号

要点:

  • (1)逗号分隔符;
  • (2)输出的各item可以是字符串,也可以是数值;当前记录的字段、变量或awk的表达式;
  • (3)如果省略item,相当于print $0;打印整行字符

实例

[root@localhost ~]# last -n 5
mageia   pts/1        192.168.0.8      Wed May 23 05:02 - 05:02  (00:00)    
root     pts/0        192.168.0.8      Thu May 17 23:23   still logged in   
logstash pts/1        192.168.0.8      Wed May 16 00:12 - 16:56  (16:43)    
root     pts/0        192.168.0.8      Sat May 12 23:27 - 23:22 (4+23:55)   
root     tty1                          Sat May 12 23:23   still logged in   

[root@localhost ~]# last -n 5 | awk '{print $1 "\t" $3}'
mageia  192.168.0.8
root    192.168.0.8
logstash    192.168.0.8
root    192.168.0.8
root    Sat

2.变量

2.1 内置变量

NF:每一行($0)拥有的字段总数

  • print NF:显示当前行的字段数;
  • print $NF:显示当前行的第NF字段的值;
    NR:目前awk所处理的是“第几行”数据;
    FS:目前的分隔字符,默认为空白字符;

实例

  • 列出每一行的账号(即$1)
  • 列出每一行的账号(即awk内的NR变量)
  • 并且说明,改行有多少字段(即awk内的NF变量)
[root@localhost ~]# last -n 5 | awk '{print $1 "\t lines:" NR "\t columes:" NF}'
mageia   lines:1     columes:10
root     lines:2     columes:10
logstash     lines:3     columes:10
root     lines:4     columes:10
root     lines:5     columes:9

2.2 自定义变量

  • -v var=value 变量名区分字符大小写;在program中直接定义

实例

//使用文件/etc/issue的行数,有多少行就显示多少行Linux
[root@localhost ~]# awk -v Final='linux' '{print Final}' /etc/issue
linux
linux
linux

3.awk的逻辑运算符

>,>=,<,<=,!=,==
  • 模式匹配符:
~:是否匹配
!~:是否不匹配
  • 逻辑操作符:
&& ,||,!
  • 函数调用:
function_name(argu1,argu2,...)
  • 条件表达式:
selector?if-true-expression:if-false-expression

4.PATTERN模式

  • (1)empty:空模式,匹配每一行;
  • (2)/regular expression/:仅处理能够被此处的模式匹配到的行;
  • (3)relational expression:关系表达式;结果有“真”有“假”;结果为“真”才会被处理;
  • (4)line ranges:行范围,不支持直接给出数字的格式;
  • (5)BEGIN/END模式
    BEGIN{}:仅在开始处理文件中的文本之前执行一次;
    END{}:仅在文本处理完成之后执行一次;

实例

//awk处理/^[ab]/ 模式匹配的行,即a或b开头的行
[root@localhost ~]# awk -F: '/^[ab]/ {print $1,$3}' /etc/passwd
bin 1
adm 3
abrt 173
avahi 70
bash 501
basher 502

//结果为真才处理,结果为假不处理
[root@localhost ~]# awk -F:'$3>=500{print $1,$3}' /etc/passwd
^C
[root@localhost ~]# awk -F:'$1~/root/{print $1,$3}' /etc/passwd
^C
//
[root@localhost ~]# cat /etc/passwd | awk -F: '$3<10 {print $1 "\t" $3}'
root    0
bin 1
daemon  2
adm 3
lp  4
sync    5
shutdown    6
halt    7
mail    8
[root@localhost ~]# awk -F: '$3<10 {print $1 "\t" $3}' /etc/passwd
root    0
bin 1
daemon  2
adm 3
lp  4
sync    5
shutdown    6
halt    7
mail    8
//awk处理2~10行
[root@localhost ~]#  awk -F: '(NR>=2&&NR<=10) {print $1}' /etc/passwd
bin
daemon
adm
lp
sync
shutdown
halt
mail
uucp

5.常用的action

  • (1)Expressions
  • (2)Control statements:if,while等:
  • (3)Compound statements:组合语句;
  • (4)input statements
  • (5)output statements

5.1.if-else

  • 语法:if(condtions) statement [else statement]
  • 使用场景:对awk取得的整行或某个字段进行条件判断;

实例

[root@localhost ~]# cat /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Sun Jul  2 04:16:54 2017
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
......
[root@localhost ~]# awk '{if($NF>5) printf $0} ' /etc/fstab
# Created by anaconda on Sun Jul  2 04:16:54 2017# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info      

5.2 while循环

  • 语法:while(condition) statement
    条件“真”,进入循环;条件“假”,退出循环;
  • 使用场景:对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用;

实例

[root@localhost ~]# cat /etc/issue
CentOS release 6.3 (Final)
Kernel \r on an \m

[root@localhost ~]# awk '{i=1;while(i<=NF){if(length($i)>=6) {print $i};i++}}' /etc/issue
CentOS
release
(Final)
Kernel

5.3 for循环

  • 语法:for(exper1;expr2;expr3) statement
  • for(variable assignment;condition;iteration process) {for-body}

实例

 [root@localhost ~]# awk '{for(i=1;i<=NF;i++){if(length($i)>=6)print $i}}' /etc/issue
CentOS
release
(Final)
Kernel
  • 特殊用法:能够遍历数组中的元素;
    语法:for(var in array) (for-body)

6.awk的输出命令之二:printf格式化输出

格式化输出:

printf FORMAT,item1,item2,...
  • (1)FORMAT必须给出;
  • (2)不会自动换行,需要显式给出换行控制符,\n
  • (3)FORMAT中需要分别为后面的每个item指定一个格式化符号;

格式符:

  • 都以%开头,后跟单个字符
%c:显示字符的ASCII码;
%d,%i:显示十进制整数;
%e,%E:科学计数法数值显示;
%f:显示浮点数;
%g,%G:以科学计数法或浮点形式显示数值;
%s:显示字符串;
%u:无符号整数;
%%:显示%自身;
修饰符:
#[.#]:第一个数字用来控制显示的宽度;第二个#表示小数点后的精度;  %3.1f
-:左对齐
+:显示数值的符号

你可能感兴趣的:(Linux文本处理三剑客——awk)