Linux三剑客之awk

除了 grep 命令外,Linux操作系统中还有两个不得不的掌握的工具--- awksedgrep 适用于从文件或终端输出中匹配指定模式的行内容, awk 作为一个文本处理工具,在处理表格类的文本是显得更加得心应手,而 sed 则更关注于针对文本完成复杂的编辑功能。

awk 是一种操作数据和生成报告的脚本语言,通过在所接收到的文本文件中逐行匹配模式并完成指定操作的功能。在 awk 表达式中,你可以自己定义使用变量、函数、字符串函数和逻辑运算符。

语法

awk [options] 'selection_criteria {action}' input-file > output-file

awk 支持的options中,如下是其中最常用的两个

  • -F fs: 使用出入的字段作为分割符
  • -f program-file: 使用出入的文件代替输入的第一个命令行参数

awk 中常用的内置变量

  • FS: (输入)字段分割符。默认为空格
  • NF: awk对输入文件处理时会使用逐行处理的方式,NF 为使用分割符对行内容进行切分后的域(字段)
  • NR: 使用时会输出在输入文件的每行前加上行号
  • RS: 指定输入记录的每行的分割符,默认RS为"\n"
  • OFS: (输出)字段分割符。默认为空格
  • ORS: 指定输出记录的每行的分割符。默认ORS为"\n"
  • BEGIN: 执行指定前先执行BEGIN变量后定义的语句
  • END: 执行指令后执行END变量后定义的语句
  • if: 使用if条件判断。格式为 '{ if(xx==xx) print xx; }'

用法

以下示例多会使用Linux操作系统上的用户文件/etc/passwd,以如下内容为例

#cat < /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
  • 默认情况下awk会逐行扫描输入文件,并输出文件的所有内容
# awk '{ print }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
  • 指定分隔符':',输出用户文件的用户名及登录所使用的终端
# awk -F':' '{ print $1,$NF }' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
  • 匹配指定模式的内容并输出切分后的指定域
    注意: NF 与 NF 的输出并不相同。NF 表示awk处理输入文件行的域,NF 表示第几域的内容
# awk -F':' ' /root/ { print $1,$NF }' /etc/passwd    # 匹配用户文件中包含root的行,并根据分割符切分出指定的域,输出第一个域和最后一个域 
root /bin/bash
# awk -F':' ' /root/ { print $1,NF }' /etc/passwd
root 7
  • 指定分割符':',并输出第一个域及对应的行号
# awk -F':' '{ print NR,$1 }' /etc/passwd
1 root
2 bin
3 daemon
4 adm
  • 指定分割符':',输出用户文件中对应用户名、用户id、组id、登录后使用的终端对应的第一、三、四、七域
# awk -F':' '{ print $1,$3,$4,$7 }' /etc/passwd
root 0 0 /bin/bash
bin 1 1 /sbin/nologin
daemon 2 2 /sbin/nologin
adm 3 4 /sbin/nologin
  • 指定(域)分割符':',并指定每行记录的分割符'****\n'输出用户文件的第一域
# awk -F':' ' RS="****\n" { print $1,RS }' /etc/passwd      # 在这里, RS="****\n" 实际上在输出的域之后加上了 ****,\n 则为换行
root ****

bin ****

daemon ****

adm ****

  • 指定(域)分割符':',输出指定多少行的记录
# awk -F':' ' NR==2,NR==4 { print NR,$1 }' /etc/passwd      # 输出2,3,4 行的第一域
2 bin
3 daemon
4 adm
# awk -F':' ' NR > 1,NR < 4 { print NR "\t" $1 }' /etc/passwd       # \t 为制表符
2   bin
3   daemon
4   adm
  • 输出文件的行记录
# awk -F':' ' END { print NR }' /etc/passwd
4
  • 执行指令前后添加输出
# awk -F':' ' BEGIN { print ">>>>>>>>>>>"} { print NR } END { print "<<<<<<<<<<<<"  } ' /etc/passwd
>>>>>>>>>>>
1
2
3
4
<<<<<<<<<<<<
# awk -F':' ' BEGIN { for(i=1;i<=5;i++) print "The num is: "i  } ' /etc/passwd
The num is: 1
The num is: 2
The num is: 3
The num is: 4
The num is: 5
  • 输出时指定输出行的域分割符
# awk -F':' ' OFS="\t" { print $1,$NF }' /etc/passwd
root    /bin/bash
bin    /sbin/nologin
daemon    /sbin/nologin
adm    /sbin/nologin
  • 输出时指定输出记录的分割符
# awk -F':' ' ORS="\n>>>>\n" { print $1,$NF }' /etc/passwd      # 每一行为一条记录,因此会在行后输出">>>>\n"
root /bin/bash
>>>>
bin /sbin/nologin
>>>>
daemon /sbin/nologin
>>>>
adm /sbin/nologin
>>>>
  • 使用if条件输出匹配的行
# awk -F':' ' { if($1=="root") print $0; } ' /etc/passwd
root:x:0:0:root:/root:/bin/bash
# awk -F':' ' { if($4>3) print $0; } ' /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
  • 输出每行记录的长度
# awk -F':' '{ print length($0) }' /etc/passwd  # $0 为每行的所有域
31
32
39
36

参考:
https://www.geeksforgeeks.org/awk-command-unixlinux-examples/
http://c.biancheng.net/view/4082.html

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容