面试官都在问 | Linux 什么命令能够进行文本列级别切分
0. 概述
AWK
是一种样式扫描与处理的工具,其功能与 sed
和 grep
命令类似,却又远远强大于它们.
AWK
不仅支持数据的扫描以及样式过滤,同时它还包含样式装入、流控制、数学运算符、进程控制语句甚至于内置变量和函数,几乎具备了一门完整编程语言的精美特性,因此,AWK
创始者们将其定义为样式、扫描、处理语言。
在我们面试各大公司的时候,关于Linux往往最容易被问到的问题之一就是Linux指令,而其中,使用AWK
命令对数据进行扫描、过滤、处理,又是相对比较容易被问到的。因此我们结合海量面经,提取出了几个最容易被问到的AWK
相关功能以及基本使用方法,供大家参考。
-
如何对数据进行过滤,匹配指定行的数据
-
如何将数据按照指定字符分割,并取出指定列的数据
-
如何对随机进行统计分析输出
1. Linux命令之 AWK
1.1 AWK
基本使用规则
规则:
awk [选项] '条件1{动作 1} 条件2{动作 2} …' 文件名
选项:
-F #指定分隔符,可省略(默认空格或Tab位)
-V #调用外部Shell变量 variable
**条件:**一般使用关系表达式作为条件。这些关系表达式非常多, 参考下表:
条件类型 | 条 件 | 说 明 |
---|---|---|
awk保留字 | BEGIN | 在 awk 程序一开始,尚未读取任何数据之前执行。 BEGIN 后的动作只在程序开始时执行一次 |
awk保留字 | END | 在 awk 程序处理完所有数据,即将结束时执行; END 后的动作只在程序结束时执行一次 |
关系运算符 | > | 大于 |
关系运算符 | < | 小于 |
关系运算符 | >= | 大于等于 |
关系运算符 | <= | 小于等于 |
关系运算符 | == | 等于,用于判断两个值是否相等。如果是给变童赋值,则使用"=” |
关系运算符 | != | 不等于 |
关系运算符 | A~B | 判断字符串 A 中是否包含能匹配 B 表达式的子字符串 |
关系运算符 | A!~B | 判断字符串 A 中是否不包含能匹配 B 表达式的子字符串 |
正则表达式 | /正则/ | 如果在“//”中可以写入字符,则也可以支持正则表达式 |
内置变量:
变量 | 用途 | 示例 |
---|---|---|
FS | 保存或设置字段分隔符,如FS=”:” | |
$n | 指定数据内容第n列数据 | awk -F ‘:’ ‘{print “用户名:”$1}’ /etc/passwd |
$0 | 当前读入的整行文本内容 | |
NF | 记录当前处理行的字段个数(列数) | awk ‘{print NF}’ a.txt |
NR | 记录当前已读入行的数量(行数) | awk ‘{print NR}’ a.txt |
FNR | 当前行在源文件中的行号 | awk ‘{print “第”FNR”行”,“有“NF”列”}’ a.txt |
2 AWK
常用选项及条件使用示例
2.1 数据内容:
[san@San doc]$ cat awk.txt
张三:87:66:55
李四:85:76:60
王五:91:53:97
2.2 AWK
命令之对数据进行过滤,匹配指定行的数据:
[san@San doc]$ awk -F ':' 'NR==2 {print}' awk.txt
李四:85:76:60
[san@San doc]$ awk -F ':' 'NR==1, NR==3 {print}' awk.txt
张三:87:66:55
李四:85:76:60
王五:91:53:97
注意:
示例 awk -F ':' awk.txt
中选项指定了文本数据内容中列与列之间的分隔符为 :
;
示例 awk 'NR==2 {print}' awk.txt
中,NR==2
为条件判断,匹配第二行数据;{print}
为执行动作,表示进行打印。
示例 NR==1, NR==3
中,匹配并非第2行以及第3行,其功能应为从第1行至第3行。
2.3 AWK
命令之对数据进行过滤,匹配指定列的数据:
[san@San doc]$ awk -F ':' 'NF==1 {print}' awk.txt
[san@San doc]$
[san@San doc]$ awk -F ':' 'NR==1,NF=1 {print}' awk.txt
张三
[san@San doc]$ awk -F ':' 'NR==1,NF=2 {print}' awk.txt
张三 87
[san@San doc]$ awk -F ':' '{printf $2 "\n"}' awk.txt
87
85
91
注意:
示例中 NF
表示指定行字段列的个数,并非指定某一列字段。因此,随着 NF
字段的变化,打印出的列的个数也不同。
若要获取某一列的数据,则需要在条件动作中进行指定 $n
来获取,使用 printf
进行打印。
2.4 AWK
命令之条件执行 BEGIN
和 END
[san@San doc]$ awk -F ':' 'BEGIN{printf "姓名\t语文\t数学\t英语\n"}
> NR==1, NR==3 {print $1"\t"$2"\t"$3"\t"$4"\n"}
> END{printf "这是大家的成绩单...\n"}' awk.txt
姓名 语文 数学 英语
张三 87 66 55
李四 85 76 60
王五 91 53 97
这是大家的成绩单...
[san@San doc]$ awk -F ':' 'BEGIN{printf "姓名\t语文\t数学\t英语\n"}; NR==1, NR==3 {print $1"\t"$2"\t"$3"\t"$4"\n"}; END{printf "这是大家的成绩单...\n"}' awk.txt
姓名 语文 数学 英语
张三 87 66 55
李四 85 76 60
王五 91 53 97
这是大家的成绩单...
注意:
示例中, 多个条件及对应动作可以以空格或者分号进行间隔,追求阅读性则可以使用换行。
示例中,BEGIN{printf "姓名\t语文\t数学\t英语\n"}
表示AWK
在处理初始阶段先完成打印标题动作。
示例中,END{printf "这是大家的成绩单...\n"}
表示AWK
在处理完毕后结束时完成打印动作
2.5 AWK
命令之匹配包含指定字符串的行
[san@San doc]$ awk -F ':' '/6/{print}' awk.txt
张三:87:66:55
李四:85:76:60
[san@San doc]$ awk -F ':' '/7$/{print}' awk.txt
王五:91:53:97
[san@San doc]$ awk -F ':' '/^李/{print}' awk.txt
李四:85:76:60
注意:
示例中, /6/
为正则表达式条件匹配 , 匹配包含有6
字符的行。
示例中,/7$/
为正则表达式条件匹配 ,匹配以7
字符结尾的行
示例中,/^李/
为正则表达式条件匹配 ,匹配以李
字符开始的行
更多字符串匹配用法,可以调研参见正则表达式的使用规则;
2.6 AWK
命令之对数据进行统计处理:
[san@San doc]$ awk -F ':' 'BEGIN{printf "姓名\t语文\t数学\t英语\t总分\n"}
{printf "%s\t%d\t%d\t%d\t%d\n", $1, $2, $3, $4, $2+$3+$4}
END{printf "成绩统计结束\n"}' awk.txt
姓名 语文 数学 英语 总分
张三 87 66 55 208
李四 85 76 60 221
王五 91 53 97 241
成绩统计结束
[san@San doc]$ awk -F ':' '{if($2>=60 && $3 >= 60 && $4 >=60){total=$2+$3+$4; printf "%s好样的,全 科通过,总分:%d\n",$1, total}}' awk.txt
李四好样的,全科通过,总分:221
注意:
从示例中,可以看出在 awk
的执行动作中,printf
也可以像C语言一样进行字符串的格式化输出,并且支持数据运算以及类C语言风格的流程控制语句。
3. 总结
awk
命令之常用高频选项awk
命令之常见条件判断awk
命令之内置变量awk
命令之常见执行动作