linux文本处理三剑客之awk的使用

文本处理三剑客系列笔记:
文本处理三剑客 – grep:https://blog.csdn.net/d1240673769/article/details/121407615
文本处理三剑客 – sed:https://blog.csdn.net/d1240673769/article/details/103723838

awk命令

awk是linux中处理文本的强大工具,或者说是一种专门处理字符串的语言,它有自己的编码格式。awk的强大之处还在于能生成强大的格式化报告。

命令格式

awk   [options]   'program'   file
  • program:pattern {action statements;…}
  • pattern和action:
    • pattern部分决定动作语句何时触发及触发事件 BEGIN, END
    • action statements:对数据进行处理,放在{}内指明 print, printf
  • 分隔符、域和记录
    • awk执行时,由分隔符分割的字段(域)标记,$1, $2,…, $n 称为域标识符。$0为所有域
    • 文件的每一行称为记录
    • 省略action,则默认执行print $0的操作

awk介绍

有多种版本:New awk(nawk),GNU awk(gawk)
gawk:模式扫描和处理语言
基本用法:

awk  [options]  'program'  var=value  file...
awk  [options]  -f  programfile.awk  var=value  file...
awk  [options]  'BEGIN{ACTION;...} pattern{action;...} END{action;...}'  file...

awk 程序通常由:BEGIN语句块、能够使用模式配的通用语句块、EMD语句块,共三部分组成
program通常在被单引号或双引号中
选项:-F 指明输入时用到的字段分隔符,-v var=value:自定义变量

awk工作原理

  • 第一步:执行 BEGIN{ACTION;…} 语句块中语句
  • 第二步:从文件或标准输入读取一行,然后执行 pattern{action;…} 语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕
  • 第三步:当读至输入流末尾时,执行 END{action;…} 语句块
  • BEGIN 语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
  • END 语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息侯总都是在END语句块中完成,它也是一个可选语句块
  • pattern 语句块中的通用命令是最重要的部分,也是可选的,如果没有提供pattern 语句块,则默认执行{ print } ,即打印每一个读取到的行,awk读取的每一行都会执行该语句块

print格式:print item1, item2, …

要点:

  • (1)逗号分隔
  • (2)输出的各item可以字符串,也可以是数值;当前记录的字段、变量或awk的表达式
  • (3)如果省略item,相当于 print $0
    示例:
awk -F: '{print}' /etc/passwd
awk -F: '{print $0}' /etc/passwd
awk -F: '{print $1}' /etc/passwd
awk -F: '{print $1"\t"$3}' /etc/passwd
awk -F: '{print "hhhhhhhh"}' /etc/passwd
tail -3 /etc/fstab |awk '{print $2,$4}'
awk 'BEGIN{print "读取/etc/passwd文件..."} {print} END{print "读取结束..."}' /etc/passwd

awk变量

有内置和自定义变量

  • FS:输入字段分隔符,默认为空白字符
awk	 -v  FS=':' '{print $1,FS,$3}'  /etc/passwd
awk	 -F: '{print $1,$2,$3}'  /etc/passwd
  • OFS:输出字段分隔符,默认为空白字符
awk -v FS=':' -v OFS=':' '{print$1,$3,$7}' /etc/passwd
  • RS:输入记录分隔符,指定输入时的换行符
awk -v RS='' '{print}' /etc/passwd
  • ORS:输出记录分隔符,输出时用指定符号代替换行符
awk -v RS='' -v ORS='###' '{print}' /etc/passwd
  • NF:字段数量
awk -F: '{print NF}' /etc/passwd  #引用内置变量不用$
awk -F: 'print $(NF-1)' /etc/passwd 
  • NR:记录号
awk '{print NR}' /etc/fstab
awk '{print} END{print NR}' /etc/fstab
  • FNR:各文件分别计数,记录号
awk '{print FNR}' /etc/fstab /etc/inittab
  • FILENAME:当前文件名
awk '{print FILENAME}' /etc/fstab
  • ARGC:命令行参数的个数
awk '{print ARGC}' /etc/fstab /etc/inittab
awk 'BEGIN{print ARGC}' /etc/fstab /etc/inittab
  • ARGV:数组,保存的是命令行所给定的各参数
awk 'BEGIN{print ARGV[0]}' /etc/fstab /etc/inittab
awk 'BEGIN{print ARGV[1]}' /etc/fstab /etc/inittab

自定义变量(区分字符大小写)
(1)-v var=value
(2)在program中直接定义(变量在program中定义时,需要使用引号引起来)

示例:

awk -v test='hello gawk' '{print test}' /etc/fstab
awk -v test='hello gawk' 'BEGIN{print test}'
awk 'BEGIN{test="hello, gawk"; print test}'
awk -F: '{sex="male"; print $1,sex,age;age=18}' /etc/passwd

printf命令

格式化输出:printf FORMAT,item1,item2…
要点:

  • 1、其与print命令最大不同是,printf需要指定format
  • 2、printf后面的字串定义内容需要使用双引号引起来
  • 3、字串定义后的内容需要使用","分隔,后面直接跟Item1,item2…
  • 4、format用于指定后面的每个item的输出格式
  • 5、printf语句不会自动打印换行符,\n

格式符:
linux文本处理三剑客之awk的使用_第1张图片
修饰符:
linux文本处理三剑客之awk的使用_第2张图片
示例:

awk '{printf "%s\n",$1}' /etc/fstab
awk -F: '{printf "username: %s,UID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "username: %15s,UID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "username: %-15s,UID:%d\n",$1,$3}' /etc/passwd
awk -F: '{printf "username: %-20s shell: %s\n",$1,$NF}' /etc/passwd

操作符

比较操作符:

== , != , > , >= , < , <=

模式匹配符:
~:左边是否和右边匹配(包含)
!~:是否不匹配

示例:

awk -F: '$0 ~ /root/' /etc/passwd
awk -F: '$0 ~ /root/{print $1}' /etc/passwd
awk '$0 ~ "^root"' /etc/passwd
awk -F: '$0 !~ /root/' /etc/passwd
awk -F: '$3==0' /etc/passwd

逻辑运算符:与&&,或||,非!

示例:

awk -F: '$3>=0 && $3>=1000' /etc/passwd
awk -F: '$3>=0 || $3>=1000' /etc/passwd
awk -F: '!($3==0) {print $1"\t"$3}' /etc/passwd
awk -F: '!($3>=500) {print $3}' /etc/passwd

条件表达式(三目表达式):

  • selector ? if-true-expression: if-false-expression
    示例:
awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser"; printf "%15s:%-s\n",$1,usertype}' /etc/passwd

awk PATTREN

pattern: 根据pattern条件,过滤匹配的行,再做处理
(1)如果未指定:空模式,匹配一行
(2)/regular expression/:仅处理能够模式匹配到的行,需要用/ / 括起来

awk '/^UUID/ {print $1}' /etc/fstab
awk '!/^UUID/ {print $1}' /etc/fstab

(3)relational expression:关系表达式,结果为真才会被处理

  • 真:结果为非0值,非空字符串
  • 假:结果为空字符串或0值
awk -F: 'i=1;j=1 {print i,j}' /etc/passwd
awk '!0' /etc/passwd
awk '!1' /etc/passwd
awk -F: '$3>=1000 {print $1,$3}' /etc/passwd
awk -F: '$NF~/bash$/ {print $1,$NF}' /etc/passwd

(4)line ranges:行范围

  • startline, endline:/pat1/,/pat2/ 不支持直接给出数字格式
awk -F: '/^root/,/^nobody/ {print $1}' /etc/passwd
awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd  # 10-20

(5)BEGIN/END 模式

  • BEGIN{}:仅在开始处理文件中的文本之前执行一次
  • END{}:仅在文本处理完成之后执行一次

你可能感兴趣的:(linux学习笔记,linux,awk)