Linux文本处理三剑客之awk
工欲善其事,必先利其器。
掌握了Linux文本三剑客,可谓是事半功倍。
对于刚接触Linux的同学来说,Linux的各种命令真的时让人望而生畏。工作中看到大神们一通操作猛如虎,各种命令以及参数眼花缭乱。
当我们用过一些命令,但又不熟悉得情况下,这个时候就得从全局入手,看看Linux有哪几类命令,先提纲挈领,至少我们能知道完成什么样得功能我需要用什么命令,至于细节参数,查手册多用几次就熟悉了。而不是每次都束手无策,盲目查找。
今天我们就来看一下Linux对于文本处理的三大利器之一awk。基本上可以满足对文本处理的所有任务。

awk
简介
AWK是Linux强大的文本处理工具,其名称由来取自于三位创始人姓氏的首字母。
AWK擅长行处理,其工作原理:
- awk会接收一行作为输入,并将这一行赋给awk的内部变量$0,每一行也可称为一个记录,行的边界是以换行符作为结束;
- 读入的行以分隔符(默认为空格,可以自己指定)分解成若干字段(或域),每个字段存储在已编号的变量中,编号从$1开始,最多达100个字段;
- 一行处理完,将从文件中获取另一行,然后覆盖给$0,继续(2)的步骤,直至所有行处理完毕。
命令格式
awk [options] 'pattern {action}' file1 file2, ...
awk [options] 'script' file1 file2, ...
pattern: 模式或条件
action: 对数据处理,常用print
常用内建变量
FS: 输入列分隔符。指定每行文本的字段分割符,默认为空格或者治标位。与“-F”作用相同
OFS: 输出列分隔符
NF: 当前处理的行的字段个数;
NR: 当前处理的行的行号;
$0: 当前处理的行的整行内容;
$n: 当前处理行的第n个字段;
FILENAME: 被处理的文件名
常用参数
-F fs or --field-separator fs
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。
-v var=value or --asign var=value
赋值一个用户定义变量。
-f scripfile or --file scriptfile
从脚本文件中读取awk命令。
基本用法
创建测试文件test.txt;
(base) rhett@LAPTOP-MV0SUCM6:~$ cat test.txt
Today is a good day, a sunny day, a wonderful day, a important day.
I am a boy, a good boy, a lovely boy.
I like reading, sports, and coding.
Enjoy coding.
案例1
按行输出:输出文件的1~3行
NR是内建变量,代表行号
(base) rhett@LAPTOP-MV0SUCM6:~$ awk '(NR>=1)&&(NR<=3)' test.txt
Today is a good day, a sunny day, a wonderful day, a important day.
I am a boy, a good boy, a lovely boy.
I like reading, sports, and coding.
案例2
按字段输出:输出每行中的第1、3个字段(默认空格分割符)
(base) rhett@LAPTOP-MV0SUCM6:~$ awk '{print $1,$3}' test.txt
Today a
I a
I reading,
Enjoy
这里的输出分隔符默认和输入一样,为空格。
我们也可以指定输出分隔符;
-v给变量赋值,这里给内建变量输出分隔符OFS赋值为“#”
(base) rhett@LAPTOP-MV0SUCM6:~$ awk -v OFS='#' '{print $1,$3}' test.txt
Today#a
I#a
I#reading,
Enjoy#
案例3
按照指定分隔符分割字段。
下面按照逗号而不是空格重新分割输出。
(base) rhett@LAPTOP-MV0SUCM6:~$ awk -v OFS='#' -F , '{print $1,$2}' test.txt
Today is a good day# a sunny day
I am a boy# a good boy
I like reading# sports
Enjoy coding.#
案例4
输出分段输大于3的行。
注意是以逗号为分隔符,只有第一行为4个字段,其他都少于等于3个字段。
(base) rhett@LAPTOP-MV0SUCM6:~$ awk -F ',' 'NF>3 {print $1,$2}' test.txt
Today is a good day  a sunny day
进阶用法
处理规则
- BEGIN{} : BEGIN是在awk处理文本之前运行
- // : 使用的匹配规则
- {} :循环(每次只处理一行数据)
- END{} :当所有的处理全部执行完毕之后,执行END中的相关操作
正则表达式
参考 https://www.runoob.com/regexp/regexp-syntax.html
案例5
匹配含有“good”的行。
(base) rhett@LAPTOP-MV0SUCM6:~$ awk '/good/' test.txt
Today is a good day, a sunny day, a wonderful day, a important day.
I am a boy, a good boy, a lovely boy.
案例6
输出文件参数
(base) rhett@LAPTOP-MV0SUCM6:~$ awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}' test.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
test.txt    2    1        14    1
test.txt    2    2        10    2
test.txt    2    3         6    3
test.txt    2    4         2    4

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号