简介
grep、sed、awk 都是文本分析工具,配合正则表达式或管道命令使用可以发挥强大的功能,被称为linux 三剑客,但三个命令各有其特点:
grep 更适合单纯的查找或匹配文本;sed 更适合编辑匹配到的文本;awk 更适合格式化文本,对文本进行较复杂格式处理。
- grep 是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来,擅长查找功能。
- sed 是一种流编辑器,它一次处理一行内容,不断重复至文件末尾。处理时把当前处理的行存储在临时缓冲区中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。sed编辑器是非破坏性的,可以使用重定向保存输出,否则它不会更改文件内容。
sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等,擅长取行或替换。 - awk 是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大,擅长列操作。
1、grep
grep 命令用于查找文件里符合正则表达式条件的字符串
grep 命令格式:
grep [option] pattern filename
option为可选择项,pattern为正则表达式,filename为目标操作文件名。
若不指定任何文件名称,则grep 指令会从标准输入设备读取数据。
常用可选项:
-i: 忽略字母的大小写
-n: 打印行号和匹配的行
-v: 打印不匹配的行
-c: 计算并返回匹配的行数
-w: 只打印完全符合字符串的行
-l: 只打印具有匹配行的文件名称
-L: 只打印不具有匹配行的文件名称
-e: 使用扩展正则模式
-r: 以递归的方式查找符合条件的文件
-A 指定行数: 除了显示符合样式的那一列之外,并显示该行之后指定行数的内容
-B 指定行数: 除了显示符合样式的那一行之外,并显示该行之前指定行数的内容
-C 指定行数: 除了显示符合样式的那一行之外,并显示该行之前后指定行数的内容
示例:
打印demo_score.txt 文件中含有math 的行及其所在行号
-w a 只打印完全匹配的行
-A1 除了显示符合样式的那一列之外,还显示该行之后指定行数(此为1行)的内容
打印当前目录下含有math 的文件的名称
2、sed
sed 可依照脚本的指令来处理、编辑文本文件
sed命令格式:
sed [option] '[command]'pattern filename
或
sed [option] [command]\pattern filename
常用的option:
-n: 表示只打印出匹配到的行
-e<script>: 以选项中指定的script来处理输入的文本文件,可省略
-f<script文件>: 以选项中指定的script文件来处理输入的文本文件
这里sed命令与grep不同在于多了一个command 选项,表示要对匹配的文本进行的操作,常用的有:
a: 新增,a 后接的内容会在当前行的下一行出现
i: 插入,i 后接的内容会在当前行的上一行出现
c: 取代,c 后接的内容可以取代n1,n2 之间的行
d: 删除行
p: 打印,将匹配到的行打印出来。通常与sed -n 一起运行
w: 另存文件
s: 替代,格式为sed ‘s/要被取代的字串/新的字串/g’
示例:
在第三行后新增add ,在第四行前插入insert
删除前两行
将前两行替换为test
查找并打印出带有math 的行
将math 替换为math_new
3、awk
awk 常用于操作数据和生成报告,格式化输出。
awk 的使用相对复杂,既可以在命令行中用于简单的操作,也可以将其写入用于大型应用程序的程序中,这里只做简单介绍。
awk命令格式:
awk [options] 'pattern{action}' file
常用的option:
-F fs: 指定文件分隔符,fs是一个字符串或者是一个正则表达式,如-F:。默认以空格或tab键为分隔符进行分隔
-v var: 赋值一个用户定义变量
-f scripfile: 从脚本文件中读取awk命令
基本用法
awk 擅长文本格式化,并将格式化后的文本输出,因此awk 最常用的动作就是print 和printf。awk 还支持条件语句、循环和数组等操作。此外,awk 有许多内建变量也支持用户自定义变量配合操作。
awk [options] 'pattern{action}' file
如:过滤第二列等于90的文本,并输出所有列
awk -F '\t' '$2==90 {print $0}' demo_score.txt
执行脚本
awk -f <script文件> file
如:用脚本cal.awk 处理文件log.txt
awk -f cal.awk log.txt
定义变量
awk -v var
如:定义a=1,输出第1列和第1+a 列
awk -va=1 '{print \$1,\$(a+1)}' demo_score.txt
指定分隔符
awk -F fs 'pattern{action}' file
- 使用","分割
awk -F, '{print $1,$2}' demo_class.txt
- 使用内建变量,用","分割
awk 'BEGIN{FS=","} {print $1,$2}' demo_class.txt
- 使用多个分隔符先使用"\t"分割,然后对分割结果再使用"|"分割
awk -F '[\t|]' '{print $1,$2,$3}' demo_class.txt
BEGIN{}{}END{} 模式
awk 有一种扩展模式:
awk -F 分隔符 BEGIN{#预处理命令}/pattern/{#逐行处理}END{#最终处理} file
- BEGIN{commands} 在程序启动还未处理文件的时候首先执行,它在整个过程中只执行一次。一般情况下,可以在其中初始化一些变量
- /pattern/{commands} 在pattern 部分匹配该行内容成功后,才会执行命令的内容
- END{commands} 在程序结束时执行
示例:
awk 'BEGIN{print sum+=$2}$2>=90{print sum+=$2}END{print sum}' demo_score.txt
可以发现,BEGIN中的命令并未处理文件,输出为0;中间部分的命令在执行过滤后才计算,并逐行处理;END命令在最后执行,输出计算的最终结果
常用内建变量
$n: 当前记录的第n个字段,字段间由FS分隔
$0: 文件中的所有字段
FS: 字段分隔符(默认是任何空格)
OFS: 输出字段分隔符,默认值与输入字段分隔符一致。
RS: 记录分隔符(默认是一个换行符)
ORS: 输出记录分隔符(默认是一个换行符)
NF: 一行中字段数量,最后一个字段内容可以用$NF取出
NR: 行号,从1开始,多文件时候也是连续接着计数
FNR: 各文件分别计数的行号,多文件的时候会和NR不同,它会重新计数
ARGC: 命令行参数的数目
ARGIND: 命令行中当前文件的位置(从0开始算)
ARGV: 包含命令行参数的数组,第一个参数是命令awk
FILENAME: 当前文件名
IGNORECASE: 如果为真,则进行忽略大小写的匹配
ERRNO: 最后一个系统错误的描述