grep、sed、awk我们叫他们三剑客,掌握它们可以更好的运维,提升工作效率,即使不是运维,对我们处理数据都是非常方便的~就很多数据处理来讲,写程序肯定是也能处理的,但是远没有已经存在特定功能的命令更高效,我们只需要操作命令即可。通过本文可以讲解三剑客的一些基础知识和实用,希望大家可以自己动手敲,毕竟自己体会过的印象更深刻,后面还会持续更新。。。
grep
简介
grep是一款强大的文本搜索工具,支持正则表达式。
全称( global search regular expression(RE) and print out the line)
语法:grep [option]… PATTERN [FILE]…
常用:
1 | 复制代码usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]] |
常用参数:
1 | 复制代码 -v 取反 |
实际使用
准备好一个小故事txt:
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# cat monkey |
直接查找符合条件的行
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# grep moon monkey |
查找反向符合条件的行
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# grep -v moon monkey |
直接查找符合条件的行数
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# grep -c moon monkey |
忽略大小写查找符合条件的行数
先来看一下直接查找的结果
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# grep my monkey |
忽略大小写查看
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# grep -i my monkey |
查找符合条件的行并输出行号
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# grep -n monkey monkey |
查找开头是J的行
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# grep '^J' monkey |
查找结尾是呢的行
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# grep "呢$" monkey |
大家可以grep –help,查看更多相关的命令,这里就不一一演示了。
小结
有了强大的网络以后,很多东西都可以在网上找到,但是基础的一定要自己
熟练掌握,才回在遇到事情的时候不慌。
sed
sed是一种流编辑器,是一款处理文本比较优秀的工具,可以结合正则表达式一起使用。
sed执行过程
sed命令
命令: sed
语法 : sed [选项]… {命令集} [输入文件]…
常用命令:
1 | 复制代码 d 删除选择的行 |
操作:
替换
查看文件:
1 | 复制代码➜ happy cat word |
替换:
1 | 复制代码➜ happy sed 's/little/big/' word |
查看文本:
1 | 复制代码➜ happy cat word1 |
全局替换:
1 | 复制代码➜ happy sed 's/to/can/g' word1 |
按行替换(替换2到最后一行)
1 | 复制代码➜ happy sed '2,$s/to/can/' word1 |
删除:
查看文本:
1 | 复制代码➜ happy cat word |
删除:
1 | 复制代码➜ happy sed '2d' word |
显示行号:
1 | 复制代码➜ happy sed '=;2d' word |
删除第2行到第四行:
1 | 复制代码➜ happy sed '=;2,4d' word |
添加行:
向前插入:
1 | 复制代码➜ happy echo "hello" | sed 'i\kitty' |
向后插入:
1 | 复制代码➜ happy echo "kitty" | sed 'i\hello' |
修改行:
替换第二行为hello kitty
1 | 复制代码➜ happy sed '2c\hello kitty' word |
替换第二行到最后一行为hello kitty
1 | 复制代码➜ happy sed '2,$c\hello kitty' word |
写入行
把带star的行写入c文件中,c提前创建
1 | 复制代码➜ happy sed -n '/star/w c' word |
退出
打印3行后,退出sed
1 | 复制代码➜ happy sed '3q' word |
awk
名字由来
创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。
强大的文本处理工具
比起sed和grep,awk不仅仅是一个小工具,也可以算得上一种小型的编程语言了,支持if判断分支和while循环语句还有它的内置函数等,是一个要比grep和sed更强大的文本处理工具,但也就意味着要学习的东西更多了。
下面来说一下awk的一些基础概念以及实际操作。
语法
常用
Usage: awk [POSIX or GNU style options] -f progfile [–] file …
Usage: awk [POSIX or GNU style options] [–] ‘program’ file …
域
类似数据库列的概念,但它是按照序号来指定的,比如我要第一个列就是2,依此类推。$0就是输出整个文本的内容。默认用空格作为分隔符,当然你可以自己通过-F设置适合自己情况的分隔符。
提前自己编了一段数据,学生以及学生成绩数据表。
列数 | 名称 | 描述 |
---|---|---|
1 | Name | 姓名 |
2 | Math | 数学 |
3 | Chinese | 语文 |
4 | English | 英语 |
5 | History | 历史 |
6 | Sport | 体育 |
8 | Grade | 班级 |
“Name Math Chinese English History Sport grade
输出整个文本
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '{print $0}' students_store |
输出第一列(姓名列)
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '{print $1}' students_store |
模式&动作
1 | 复制代码awk '{[pattern] action}' {filenames} |
模式
pattern
可以是
- 条件语句
- 正则
模式的两个特殊字段 BEGIN 和 END (不指定时匹配或打印行数)
- BEGIN : 一般用来打印列名称。
- END : 一般用来打印总结性质的字符。
动作
action 在{}内指定,一般用来打印,也可以是一个代码段。
示例
给上面的文本加入标题头:
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {print "Name Math Chinese English History Sport grade\n----------------------------------------------"} {print $0}' students_store |
仅打印姓名、数学成绩、班级信息,再加一个文尾(再接再厉):
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {print "Name Math grade\n---------------------"} {print $1 2 "\t" $7} END {print "continue to exert oneself"}' students_store |
结合正则
像grep和sed也是支持正则表达式的。这边就不介绍正则表达式了,如果有兴趣,我单出一个文章。
使用方法:
符号 ~ 后接正则表达式
此时我们再加入一条后来的新同学,并且没有分班。
先来看下现在的数据
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# cat students_store |
模糊匹配|查询已经分班的学生
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '$0 ~/class/' students_store |
精准匹配|查询1班的学生
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '$7=="class-1" {print $0}' students_store |
反向匹配|查询不是1班的学生
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '$7!="class-1" {print $0}' students_store |
比较操作
查询数学大于80的
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '$2>60 {print $0}' students_store |
查询数学大于英语成绩的
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '$2 > $4 {print $0}' students_store |
匹配指定字符中的任意字符
在加一列专业,让我们来看看憨憨们的专业,顺便给最后一个新来的同学分个班吧。
然后再来看下此时的数据。
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# cat students_store |
或关系匹配|查询1班和3班的学生
1 | 复制代码root@iz2ze76ybn73dvwmdij06zz ~]# awk '$0 ~/(class-1|class-3)/' students_store |
任意字符匹配|名字第二个字母是
字符解释:
^ : 字段或记录的开头。
. : 任意字符。
1 | 复制代码root@iz2ze76ybn73dvwmdij06zz ~]# awk '$0 ~/(class-1|class-3)/' students_store |
复合表达式
&& AND
的关系,必同时满足才行哦~
查询数学成绩大于60并且语文成绩也大于60的童鞋。
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '{ if ($2 > 60 && $3 > 60) print $0}' students_store |
|| OR
查询数学大于80或者语文大于80的童鞋。
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '{ if ($2 > 80 || $4 > 80) print $0}' students_store |
printf 格式化输出
除了能达到功能以外,一个好看的格式也是必不可少的,因此格式化的输出看起来会更舒服哦~
语法
printf ([格式],参数)
printf %x(格式) 具体参数 x代表具体格式
符号 | 说明 |
---|---|
- | 左对齐 |
Width | 域的步长 |
.prec | 最大字符串长度或小数点右边位数 |
格式转化符
其实和其他语言大同小异的
常用格式
符号 | 描述 |
---|---|
%c | ASCII |
%d | 整数 |
%o | 八进制 |
%x | 十六进制数 |
%f | 浮点数 |
%e | 浮点数(科学记数法) |
% s | 字符串 |
%g | 决定使用浮点转化e/f |
具体操作示例
ASCII码🐎
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# echo "66" | awk '{printf "%c\n",$0}' |
浮点数
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {printf "%f\n",100}' |
16进制数
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {printf "%x",996}' |
更多操作,小伙伴有兴趣可以挨个试试~
内置变量
频率较高常用内置变量
NF : 记录浏览域的个数,在记录被读后设置。
NR : 已读的记录数。
FS : 设置输入域分隔符
A R G C : 命令行参数个数,支持命令行传入。
RS : 控制记录分隔符
FIlENAME : awk当前读文件的名称
操作
输出学生成绩表和域个数以及已读记录数。
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk '{print $0, NF , NR}' students_store |
内置函数
常用函数
length(s) 返回s长度
index(s,t) 返回s中字符串t第一次出现的位置
match (s,r) s中是否包含r字符串
split(s,a,fs) 在fs上将s分成序列a
gsub(r,s) 用s代替r,范围全文本
gsub(r,s,t) 范围t中,s代替r
substr(s,p) 返回字符串s从第p个位置开始后面的部分(下标是从1 开始算的,大家可以自己试试)
substr(s,p,n) 返回字符串s从第p个位置开始后面n个字符串的部分
操作
length
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {print length(" hello,im xiaoka")}' |
index
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {print index("xiaoka","ok")}' |
match
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {print match("Java小咖秀","va小")}' |
gsub
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'gsub("Xiaoka","xk") {print $0}' students_store |
substr(s,p)
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {print substr("xiaoka",3)}' |
substr(s,p,n)
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# awk 'BEGIN {print substr("xiaoka",3,2)}' |
split
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# str="java,xiao,ka,xiu" |
awk脚本
前面说过awk是可以说是一个小型编程语言。如果命令比较短我们可以直接在命令行执行,当命令行比较长的时候,可以使用脚本来处理,比命令行的可读性更高,还可以加上注释。
写一个完整的awk脚本并执行步骤
1.先创建一个awk文件
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# vim printname.awk |
2.脚本第一行要指定解释器
1 | 复制代码#!/usr/bin/awk -f |
3.编写脚本内容,打印一下名称
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# cat printname.awk |
4.既然是脚本,必不可少的可执行权限安排上~
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# chmod +x printname.awk |
5.有了可执行权限,我们来执行下看结果
1 | 复制代码[root@iz2ze76ybn73dvwmdij06zz ~]# ./printname.awk |
了解了写awk脚本的步骤以后大家就可以自己去写一波了~
相关内容还有很多,容我后续再分享~
后面还会继续完善我的Linux实战命令小手册,持续更新中。。。
感谢小伙伴们的支持抱拳了
今天又到了一本书,持续更新。。⛽️
参考
《awk介绍》
《Linux命令行与shell脚本》
《鸟哥的Linux私房菜》
《快乐的命令行》
百度百科
本文使用 mdnice 排版
本文转载自: 掘金