文本处理利器Linux Awk这样入门☛常见变量的使用

Posted ShenLiang2025

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文本处理利器Linux Awk这样入门☛常见变量的使用相关的知识,希望对你有一定的参考价值。

                            Linux awk常见变量初识案例

 

声明与简介

简介

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。awk通常用来处理结构化(固定格式)的文本文件, awk每接收文件的一行,然后执行相应的命令来处理文本。

本文是对awk的初步认识,主要结合数据以案例形式介绍内置变量的使用。

 

数据说明

员工表全量

1 emp.txt如下是使用的示例文本(emp.txt)数据,这里的行号是为了方便解释结果,不是文本内容。

1 7369,smith,clerk,7902,'1980-12-17',800,null,20
2 7499,allen,salesman,7698,'1981-2-20',1600,300,30
3 7521,ward,salesman,7698,'1981-2-22',1250,500,30
4 7566,jones,manager,7839,'1981-4-2',2975,null,20
5 7654,martin,salesman,7698,'1981-9-28',1250,1400,30
6 7655,jack,manager,7698,'1987-3-28',1600,1800,10
7 7656,tim,clerk,7902,'1982-12-12',1400,1400,30
8 7657,kate,clerk,7902,'1989-11-11',1400,1800,10
9 7698,blake,manager,7839,'1981-5-1',2850,null,30
10 7699,dlake,salesman,7839,'1983-6-15',3000,null,10
11 7782,clark,manager,7839,'1981-1-9',2450,null,10
12 7788,scott,analyst,7566,'1982-12-9,3000,null,20,scott
13 7839,king,president,null,'1981-11-17',5000,null,10
14 7844,turner,salesman,7698,'1981-12-8',1500,0,30
15 7876,adams,clerk,7788,'1983-1-12',1100,null,20
16 7900,james,clerk,7698,'1981-12-3',950,null,30
17 7902,ford,analyst,7566,'1981-12-3',3000,null,20
18 7934,miller,clerk,7782,'1982-1-23',1300,null,10

部分员工表多分隔符

2 emp_plus.txt ,emp.txt的前三条记录

1 7369:smith@clerk#7902$'1980-12-17'
2 7499:allen@salesman#7698$'1981-2-20'
3 7521:ward@salesman#7698$'1981-2-22'

多行非换行分割

3 emp_mutiple.txt 里列分隔符是换行,但记录分隔符是“#”

7369
smith
clerk
7902
1980-12-17
#
7499
allen
salesman
7698
1981-2-20

员工表3条记录 


4 emp_3_only.txt 员工表的前3条记录

7369,smith,clerk,7902,'1980-12-17',800,null,20
7499,allen,salesman,7698,'1981-2-20',1600,300,30
7521,ward,salesman,7698,'1981-2-22',1250,500,30

员工表4条记录 

5 emp_4_only.txt 员工表的前4条记录

7369,smith,clerk,7902,'1980-12-17',800,null,20
7499,allen,salesman,7698,'1981-2-20',1600,300,30
7521,ward,salesman,7698,'1981-2-22',1250,500,30
7900,james,clerk,7698,'1981-12-3',950,null,30

常见命令

打印命令

打印命令print即将文本的内容打印出来。

打印文本所有内容

# 打印出所有的员工的信息。
awk {print} emp.txt
# sed等价于
sed -n 'p' emp.txt
# 结果(略),这里即数据文件的全部内容。

打印文本部分列 

# 打印出所有的员工员工号。此时显示的不是第一列的内容,原因是awk默认以空格作为列的分割符。而当前文件里是以逗号作为分隔符。
awk {print $1} emp.txt
# 正确的写法
awk -F',' '{print $1}' emp.txt
# 结果(部分)
7369
7499
7521
7566

#注:特别的 $0代表的是整个文本的记录

打印文本最后一列 

# 打印最后一列所有员工的部门编号,这里借助下文介绍的NR变量(记录行数)。
awk -F',' '{print $NF}' emp.txt
#结果(部分数据)
20
30
30

打印文本最后三列 

#打印倒数第三列所有员工的部门编号,可以通过NF-2来实现,即:
awk -F',' '{print $(NF-2)}' emp.txt
#结果(部分数据)
800
1600
1250
2975

 模式匹配

模式匹配命令即是通过//来匹配关键字,也支持正则表达式。

匹配关键字

# 找出职位是manager的员工号和到岗日期。
awk -F',' '/manager/{print $1,$5}' emp.txt
# 结果
7566 '1981-4-2'
7655 '1987-3-28'
7698 '1981-5-1'
7782 '1981-1-9'


正则匹配

# 找出员工号以78开头的员工信息
awk -F',' '/^78/{print $0}' emp.txt
7839,king,president,null,'1981-11-17',5000,null,10
7844,turner,salesman,7698,'1981-12-8',1500,0,30
7876,adams,clerk,7788,'1983-1-12',1100,null,20
# 找出部门号是30的员工信息
awk -F',' '/30$/{print $0}' emp.txt
# 结果(部分数据)
7499,allen,salesman,7698,'1981-2-20',1600,300,30
7521,ward,salesman,7698,'1981-2-22',1250,500,30
7654,martin,salesman,7698,'1981-9-28',1250,1400,30

内置变量

即awk内置的系统变量,如FS、OFS、NR、RS、ORS等变量。

输入列分隔符

FS((Field Separator))变量可以指定输入字段的分隔符,即读取文件时列的分割符号。

指定单个字段分隔符

# 指定文件的分隔符为逗号,这里通过FS变量的方式。
awk '{FS=","} {print $1,$2}' emp.txt
# 结果,即第1、2列全部数据。这里略。

 指定多个字段分隔符

# 如果原始文件各个列指定的分隔符不一致,则需要自己设定。
awk 'BEGIN {FS="[:@#$]"} {print $1,$2,$3,$4}' emp_plus.txt
#结果
7369 smith clerk 7902
7499 allen salesman 7698
7521 ward salesman 7698
# 如果不加BEGIN,则从第2行开始应用awk逻辑
awk '{FS="[:@#$]"} {print $1,$2,$3,$4}' emp_plus.txt 
#结果为,第1行未应用awk逻辑。
7369:smith@clerk#7902$'1980-12-17'   
7499 allen salesman 7698
7521 ward salesman 7698
#注:这里需要特别强调,针对字段分隔符在大括号即“{}”执行时,如果在大括号前不加begin则从第2行开始匹配,第1行打印的是原始数据。如果加了则从第一行开始适配(应用awk逻辑)。

#延展阅读,关于单独使用BEGIN,注意这里得大写。
# BEGIN可以不和END一起使用,即单独使用。其中一个应用场景是,AWK后面没有跟要处理的文件。比如
# 打印出字符串Nothing
awk 'BEGIN {print "Nothing"}'
# 如下不加BEGIN是用户用户干预(按下Enter即回车)才有输入,且会一直执行。
awk '{print "Nothing"}'

输出字段分隔符

OFS(Output Field Separator)变量可以指定输入字段的分隔符 即读输出时列的分割符号。

指定字段分隔符

# Way1 打印第1、2列并以#作为分割符。
awk -F',' '{print $1,"#", $2}' emp.txt
#结果,部分数据
7369 # smith
7499 # allen
7521 # ward
# Way2 打印第1、2列并以#作为分割符。这里使用OFS参数即Output Field Separator。
awk -F',' 'BEGIN {OFS="#"} {print $1,$2}' emp.txt
#结果,部分数据
7369#smith
7499#allen
7521#ward
#注: 1 这里way1和way2的结果是不一样的。Way1里有空格,而Way2则没有空格。
#    2 输出列分隔符时不能指定多个特定的分隔符,只能是一个固定的符号。

输入记录分割符

RS(Record Separator)变量可以指定文本输入的记录分隔符,即读取文件里每一行的分割符号。我们知道一般在windows里行分隔符是回车、换行(CR 、LF)对应ASSII码分别是13、10,符号对应\\r、\\n。

非换行符的记录分割

#通过cat查看文件里的隐藏字符
cat -A awk_rs.txt 
# 结果,注意这里的制表符是以^I的形式展示,行的结尾是$。
7369,smith,clerk,7902,'1980-12-17',800,null,20^I7499,allen,salesman,7698,'1981-2-20',1600,300,30^I7521,ward,salesman,7698,'1981-2-22',1250,500,30$
# Notepad++ 方式查看

# 对awk_rs.txt的文本进行记录的分割(\\t),列间的分隔符仍是逗号。
awk -F',' 'BEGIN {RS="\\t"} {print $1,$2,$3}' awk_rs.txt
#结果
7369 smith clerk
7499 allen salesman
7521 ward salesman

换行符为列分隔符的分割

# 针对换行符为列分隔符,指定字符如#为记录分割符的情况,对记录按照列进行拆分(打印)。
awk -F'\\n' 'BEGIN {RS="#\\n"} {print $1,$2,$3}' emp_mutiple.txt 
#结果
7369 smith clerk
7499 allen salesman

输出记录分割符

ORS(Output Record Separator)变量可以指定文本输出的记录分隔符,即经过awk处理后输出来的记录分隔符。

非换行符的记录分割

#解析emp.txt并输出时以换行#换行(\\n#\\n)为输出记录分隔符。
awk -F',' 'BEGIN {RS="\\n";ORS="\\n#\\n"} {print $1,$2,$3}' employee.txt
#结果,部分数据
7369 smith clerk
#
7499 allen salesman
#
7521 ward salesman
#

打印行号

NR(number of record)是文本的行号,即文本的Line Number(行序号),这里行是以执行的记录分隔符,不一定都是换行符(\\n)。

打印文本序号

# 打印所有员工的所在行号和雇员编号。
awk -F',' '{print NR,$1}' emp.txt
#结果(部分数据)
1 7369
2 7499
3 7521

文件名

FILENAME变量主要返回当前处理文件的文件名,用于多文件处理的情景。

打印文件名

# 打印当前处理的文件的名字,结果和该文件的行数一样。
awk '{print FILENAME}' emp_plus.txt
# 结果
emp_plus.txt
emp_plus.txt
emp_plus.txt

多文件记录行数

FNR(File Number Of records)记录数,即多文件文本的总行数,这里行是以执行的记录分隔符,不一定都是换行符(\\n)。

分开统计多文件行号

#通过多文件记录FRS变量来分别统计多文件的行号和列信息。 
awk 'BEGIN{FS=","} \\
> {print FILENAME "记录数:",FNR,$1;} \\
> END {print "总记录数:",NR}' \\
> emp_3_only.txt emp_4_only.txt

# 结果
emp_3_only.txt记录数: 1 7369
emp_3_only.txt记录数: 2 7499
emp_3_only.txt记录数: 3 7521
emp_3_only2.txt记录数: 1 7369
emp_3_only2.txt记录数: 2 7499
emp_3_only2.txt记录数: 3 7521
emp_3_only2.txt记录数: 4 7900
总记录数: 7

# 注:1 这里awk脚本换行输入时需要加上空格\\。

整体统计多文件行号

#通过单文件记录RS遍历来整体统计多文件的行号和列信息。
awk 'BEGIN{FS=","} \\
> {print FILENAME "记录数:",NR,$1;} \\
> END {print "总记录数:",NR}' \\
> emp_3_only.txt emp_4_only.txt
#结果
emp_3_only.txt记录数: 1 7369
emp_3_only.txt记录数: 2 7499
emp_3_only.txt记录数: 3 7521
emp_4_only.txt记录数: 4 7369
emp_4_only.txt记录数: 5 7499
emp_4_only.txt记录数: 6 7521
emp_4_only.txt记录数: 7 7900
总记录数: 7

问题

有问题,请在评论区留言。

以上是关于文本处理利器Linux Awk这样入门☛常见变量的使用的主要内容,如果未能解决你的问题,请参考以下文章

讲清楚,说明白!Linux从业人员必备工具--AWK文本处理利器实战

05-Linux文本处理-awk

打开高效文本编辑之门_Linux Awk自定义变量与操作符

awk入门

awk入门

awk快速入门