siwen

siwen

😉

awk 命令

awk 文本分析工具#

说明:

awk 是一种编程语言,用于在 linux/uniⅸ 下对文本和数据进行处理。数据可以来自标准输入 (stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是 linux/unix 下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk 有很多内置的功能,比如数组、函数等,这是它和 C 语言的相同之处,灵活性是 awk 最大的优势。

语法:

awk [option] 'PATTERN{ACTION STATEMENTS}' FILE

awk 执行过程#

image

awk 程序结构#

结构解释
BEGIN{ awk-commands }可省略,里面的内容在 awk 读取文件之前执行
/pattern/{ awk-commands }可省略,对于输入的每一行,都会执行一次该部分代码,可以添加 /parttern/ 对输入行进行过滤
END{ awk-commands }可省略,里面的内容在 awk 读取文件完毕之后执行

示例#

# 准备如下文本内容
[root@localhost ~]# cat emp.txt 
001 张三 1000 10
002 李四 2000 10
003 王五 3000 10
004 赵六 2000 20
005 小红 1800 30
006 小丽 800  20

# 用awk命令输出文本内容
[root@localhost ~]# awk '{print}' emp.txt

# 输出文本内容,添加表头和表的结尾(-------------------)
[root@localhost ~]# awk 'BEGIN{print "编号 姓名 工资 部门"}{print}END{print "-------------------"}' emp.txt
编号 姓名 工资 部门
001 张三 1000 10
002 李四 2000 10
003 王五 3000 10
004 赵六 2000 20
005 小红 1800 30
006 小丽 800  20
-------------------

awk 命令选项#

选项含义
-F fs指定输入文件分隔符(默认是空白字符),fs 是一个字符串或者是一个正则表达式
-v var=value赋值一个用户定义变量
-f scriptfile从脚本文件中读取 awk 命令

awk 使用方式:

  • 命令行使用

直接在命令行里执行 awk 命令

awk '{print}' emp.txt
  • awk 脚本使用

将 awk 代码写在文件里(一般以.awk 为文件扩展名), 通过 -f 选项执行

awk -f file.awk emp.txt
  • shell 脚本使用

将 awk 命令写到 shell 脚本里,执行 shell 脚本

awk 模式和操作#

模式含义
/pattern/正则表达式
关系表达式使用运算符进行操作
模式匹配表达式~ (匹配) !~ (不匹配)

操作可以由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开
awk 正则范围:

  • /start/,/end/
  • NR==1,NR==5 从第 1 行开始第 5 行结束

示例#

# 输出emp.txt包含'小'字的行
[root@localhost ~]# awk '/小/' emp.txt

# 输出从包含'张'的行开始到包含'赵'的行结束
[root@localhost ~]# awk '/张/,/赵/' emp.txt

# 输出前三行
[root@localhost ~]# awk 'NR<=3' emp.txt
[root@localhost ~]# awk 'NR==1,NR==3' emp.txt
[root@localhost ~]# awk 'NR>=1 && NR<=3' emp.txt

# 模式匹配则输出
[root@localhost ~]# awk '666 ~ /[0-9]+/' emp.txt

当使用模式后,如果只是输出行,awk 语句部分可省略

awk 变量#

内置变量(预定义变量)#

变量含义
$0执行过程中当前行的内容
$n当前记录的第 n 个字段(分割后的第 n 列)
NF当前行的字段数,$NF 表示一行中最后一个字段
NR当前行的行号
FS输入字段分隔符(默认是空白字符,可使用 - v 指定)
OFS输出字段分隔符(默认是一个空格,可使用 - v 指定)
RS输入记录分隔符(默认是一个换行符,可使用 - v 指定)
ORS输出记录分隔符(默认是一个换行符,可使用 - v 指定)
FILENAME当前文件的文件名

自定义变量#

  • 使用 - v 选项定义
-v var=value
  • awk 程序中定义
awk 'BEGIN{var=value}'

传递外部变量#

  • 使用 -v 选项可以给 awk 命令传递一个外部变量

  • 在命令最后使用 var=value 也可以传递一个外部变量

示例#

# 打印emp.txt每一行的内容、行号和字段数
[root@localhost ~]# awk '{print $0,NR,NF}' emp.txt

# 打印第1列、最后一列和倒数的2列的内容
[root@localhost ~]# awk '{print $1,$NF,$(NF-1)}' emp.txt

# 将文本内容按照 "部门 编号 姓名 工资" 的顺序输出
[root@localhost ~]# awk '{print $4,$1,$2,$3}' emp.txt

# 输出第3行的第2个字段 
[root@localhost ~]# awk 'NR==3{print $2}' emp.txt

# 统计每个部门的人数 
[root@localhost ~]# awk '{print $NF}' emp.txt | uniq -c

# 将输出字段分隔符修改为':' 并把输出结果写入emp.txt.bak文件 
[root@localhost ~]# awk -v OFS=":" '{print $1,$2,$3,$4}' emp.txt > emp.bak.txt
[root@localhost ~]# awk -v OFS=":" 'NF=NF' emp.txt > emp.bak.txt

# 针对emp.txt.bak文件每一行数据,输出: "编号:xxx,姓名:xxx,工资:xxx"
[root@localhost ~]# awk -F: '{print "编号:"$1",姓名:"$2",工资:"$3}' emp.bak.txt

# 自定义变量
# 方式一
[root@localhost ~]# echo | awk -v a=100 '{print a}'
# 方式二
[root@localhost ~]# echo | awk 'BEGIN{b=100;print b}'

# 传递外部变量
[root@localhost ~]# a='aaa'
[root@localhost ~]# b='bbb'
# 方式一
[root@localhost ~]# echo | awk -v v1=$a -v v2=$b '{print v1,v2}'
# 方式二
[root@localhost ~]# echo | awk '{print v1,v2}' v1=$a v2=$b
  • print 的参数以逗号分隔时,打印时以空格作为分隔符;awkprint 语句的引号被作为拼接符使用
    - 要使 OFS 变量生效,必须对字段进行操作(可以设置 NF=NFNF+=0$1=$1 ...)

格式化打印(printf)#

  • 使用方式和 C 语言的 printf 一样
  • print 显示结果时以逗号分隔,结果会自动将这些内容用分隔符进行分隔,并且不需要添加换行符;
  • printf 可以控制某一个字段的输出格式,需要手动添加换行符

常用格式替换符:

符号解释
%s字符串
%f浮点数
%d十进制整数
%cASCII 字符
%%% 本身

常用转义字符:

符号解释
\n换行
\t水平制表符
\v垂直制表符
\r回车
\b后退
\f换页
\a警告字符
\\\ 本身
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。