Linux 三剑客 Awk、Sed、Grep 命令详解

Stella981
• 阅读 825

点击上方“民工哥技术之路”,选择“设为星标”

回复“1024”获取独家整理的学习资料!

Linux 三剑客 Awk、Sed、Grep 命令详解

Linux三剑客Awk命令详解

命令名称

Awk  pattern scanning and processing language

命令作用

对文本和数据进行处理

详细说明

awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输(stdin)、一个或多个文件,或其它命令的输出。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。

语法格式

awk [options] 'scripts' var=value filename

常用参数

  • -F 指定分隔符(可以是字符串或正则表达式)

  • -f 从脚本文件中读取awk命令

  • -v var=value 赋值变量,将外部变量传递给awk

脚本基本结构

awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' filename

一个awk脚本通常由BEGIN语句+模式匹配+END语句三部分组成,这三部分都是可选项

工作原理:

  • 第一步执行BEGIN 语句

  • 第二步从文件或标准输入读取一行,然后再执行pattern语句,逐行扫描文件到文件全部被读取

  • 第三步执行END语句

实例展示:

echo "hello " | awk 'BEGIN{ print "welcome" } END{ print "2017-08-08" }'welcome2017-08-08echo -e "hello" | awk 'BEGIN{ print "welcome" } {print} END{ print "2017-08-08" }'welcomehello2017-08-08#不加print参数时默认只打印当前的行echo|awk '{ a="hello"; b="nihao"; c="mingongge"; print a,b,c; }'hello nihao mingongge#使用print以逗号分隔时,打印则是以空格分界echo|awk '{ a="mgg"; b="mingg"; c="mingongge"; print a" is "b" or "c; }'mgg is mingg or mingongge#awk的print语句中双引号其实就是个拼接作用

Awk的变量

内置变量

$0   #当前记录$1~$n #当前记录的第N个字段FS   #输入字段分隔符(-F相同作用)默认空格RS   #输入记录分割符,默认换行符NF   #字段个数就是列 NR   #记录数,就是行号,默认从1开始OFS  #输出字段分隔符,默认空格ORS  #输出记录分割符,默认换行符 

外部变量

[mingongge@ ~]#a=100[mingongge@ ~]#b=100[mingongge@ ~]#echo |awk '{print v1*v2 }' v1=$a v2=$b10000

Awk运算与判断

算术运算符

+ - 加减* / & 乘 除 求余^ *  求幂++ -- 增加或减少,作为前缀或后缀

[mingongge@ ~]#awk 'BEGIN{a="b";print a,a++,a--,++a;}'b 0 1 1[mingongge@ ~]#awk 'BEGIN{a="0";print a,a++,a--,++a;}'0 0 1 1[mingongge@ ~]#awk 'BEGIN{a="0";print a,a++,--a,++a;}'0 0 0 1#和其它编程语言一样,所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0

赋值运算符

= += -= *= /= %= ^= **=

正则运算符

~ !~  匹配正则表达式/不匹配正则表达式

逻辑运算符

||  &&  逻辑或  逻辑与

关系运算符

< <= > >= != = 

其它运算符

$   字段引用 空格 字符串链接符?:   三目运算符ln   数组中是否存在某键值

Awk正则

^    行首定位符$    行尾定位符.    匹配任意单个字符*    匹配0个或多个前导字符(包括回车)+    匹配1个或多个前导字符?    匹配0个或1个前导字符 []   匹配指定字符组内的任意一个字符/^[ab][^]  匹配不在指定字符组内的任意一个字符()   子表达式|    或者\    转义符~,!~ 匹配或不匹配的条件语句x{m} x字符重复m次x{m,} x字符至少重复m次X{m,n} x字符至少重复m次但不起过n次(需指定参数-posix或--re-interval)

Linux三剑客Sed命令详解

命令名称

Sed 一个强大的流式文本编辑器

详细说明

sed是一种流编辑器,也是文本处理中非常好的工具,配合正则使用更强大处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区的内容,完成后输出到屏幕,接着处理下一行.

命令格式

 sed [options] 'command' file(s) sed [options] -f scriptfile file(s)

常用参数

-e #以指定的指令来处理输入的文本文件-n  #取消默认输出(如果和p命令同时使用只会打印发生改变的行)-h #帮助-V #显示版本信息

常用命令

a #在当前行下面插入文本i #在当前行上面插入文本c #把选定的行改为新的文本d #删除,删除选择的行D #删除模板块的第一行 s #替换指定字符h #拷贝模板块的内容到内存中的缓冲区H #追加模板块的内容到内存中的缓冲区g #获得内存缓冲区的内容,并替代当前模板块中的文本 G #获得内存缓冲区的内容,并追加到当前模板块文本的后面 l #列表不能打印字符的清单n #读取下一个输入行,用下一个命令处理新的行而不是用第一个命令N #追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码p #打印匹配的行P #(大写)打印模板的第一行q #退出Sedb #lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾r #file 从file中读行t #label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾T #label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾w #file 写并追加模板块到file末尾**W #file 写并追加模板块的第一行到file末尾**! #表示后面的命令对所有没有被选定的行发生作用** = #打印当前行号码**# #把注释扩展到下一个换行符以前**

Sed替换命令

g #表示行内全面替换(全局替换配合s命令使用)p #表示打印行 w  #表示把行写入一个文件 x #表示互换模板块中的文本和缓冲区中的文本 y #表示把一个字符翻译为另外的字符(但是不用于正则表达式) 1  #子串匹配标记 & #已匹配字符串标记

Sed正则

^ #匹配行开始 $ #匹配行结束. #匹配一个非换行符的任意字符* #匹配0个或多个字符[] #匹配一个指定范围内的字符[^]  #匹配一个不在指定范围内的字符 (..) #匹配子串&  #保存搜索字符用来替换其他字符< #匹配单词的开始>  #匹配单词的结束x{m} #重复字符x,m次x{m,} #重复字符x,至少m次 x{m,n} #重复字符x,至少m次,不多于n次

Sed常用实例

1、替换操作

echo "hello world" |sed 's/ /-/1g'hello-world #从第一个空格开始全局替换成-,只不过文本中只有一个空格

2、删除操作

sed '/^$/d' filename #删除空白行sed '2d' filename #删除第二行sed '2,$d' filename #删除第二直到未尾所有行sed '$d' filename #删除最后一行sed '/^test/'d filename #删除以test开头行

3、匹配替换

echo "hello world" |sed 's/w+/[&]/g'[hello] [world]echo "hello world" |sed 's/w+/"&"/g'"hello" "world"#w+匹配每一个单词,&表示匹配到的字符串echo AAA bbb |sed 's/([A-Z]+) ([a-z]+)/[2] [1]/'[bbb] [AAA]#子串匹配替换

4、选定范围

sed -n '/= 0/,/max/p' svnserve.conf#min-encryption = 0#max-encryption = 256#所有在=0到max范围内的行都会被打印出来

5、sed多点编辑功能(-e)

[root@centos001 ~]#cat -n test 1  this is a test file2  welcome3  to4  here5  hello WORLD67  linux centos6.88  redhatsed -e '2,6d' -e 's/linux centos6.8/Linux Centos6.8/' testthis is a test fileLinux Centos6.8redhat#如果两条命令功能一样,那么就需要用到下面的参数sed --expression='s/linux centos6.8/Linux Centos6.8/' --expression='s/to/TO/' test**this is a test filewelcomeTOherehello WORLDLinux CenTOs6.8redhat

6、读入与写入

[root@centos001 ~]#cat test1welcom to here[root@centos001 ~]#sed '/here/r test1' testthis is a test filewelcometohere#welcomtohere#hello WORLDlinux centos6.8redhat#将test1的文件内容读取显示所有匹配here行的后面sed -n '/centos6.8/w test2' test[root@centos001 ~]#cat test2linux centos6.8#将test文件匹配到centos6.8的所有行都写入到test2文件中,文件可以不存在.#如果文件存在,就会被重定向不是追加

7、追加与插入

[root@centos001 ~]#sed '/^l/a2017-08-08' test2linux centos6.82017-08-08#在匹配以l开头的行的后面追加2017-08-08[root@centos001 ~]#sed '1a2017-08-08' test2linux centos6.82017-08-08#在第一行的后面追加2017-08-08[root@centos001 ~]#sed '/^l/i2017-08-08' test22017-08-08linux centos6.8#在匹配以l开头的行的前面插入2017-08-08#######以上操作是不会改变文件内容################[root@centos001 ~]#sed -i '/^l/i2017-08-08' test2[root@centos001 ~]#cat test22017-08-08linux centos6.8

8、其它命令实例

[root@centos001 ~]#cat -n test2 1 2017-08-08 2 linux centos6.8 3 08 4 5 test[root@centos001 ~]#**sed '/08/{ n; s/l/L/; }' test22017-08-08Linux centos6.808test#如果08匹配到就跳到下一行,将小写l替换成大写,注意到第三行也是被匹配到#但是后面的条件不满足,所有没有被替换[root@centos001 ~]#sed '1,4y/8/9/' test22017-09-09linux centos6.909test#将1至4行所有的数字8替换成9[root@centos001 ~]#**sed '1q' test2**2017-08-08#打印第一行内容后退出

9、打印奇数或公偶数行

[root@centos001 ~]#sed -n 'p;n' test22017080808[root@centos001 ~]#sed -n 'n;p' test2linux centos6.8test[root@centos001 ~]#sed -n '1~2p' test22017080808[root@centos001 ~]#sed -n '2~2p' test2linux centos6.8test

10、打印匹配字符串行的下一行

[root@centos001 ~]#sed -n '/linux/{n;p}' test208[root@centos001 ~]#awk '/linux/{getline; print}' test208

Linux三剑客Grep 命令详解

命令名称

grep

命令作用

文本查找或搜索工具

详细说明

同样可以配合正则表达式来搜索文本,并将匹配的行打印输出,也可用于过滤与搜索特定字符串,使用十分灵活

常用参数

-a  #不要忽略二进制数据-A  #除了显示符合范本样式的那一行之外,并显示该行之后的内容-b  #在显示符合范本样式的那一行之外,并显示该行之前的内容-B  #除了显示符合样式的那一行之外,并显示该行之前的内容-c  #计算符合范本样式的列数-C  #除了显示符合范本样式的那一列之外,并显示该列之前后的内容-d  #当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作-e  #指定字符串作为查找文件内容的范本样式-E  #将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式-f  #指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式-F  #将范本样式视为固定字符串的列表-G  #将范本样式视为普通的表示法来使用-h  #在显示符合范本样式的那一列之前,不标示该列所属的文件名称-H  #在显示符合范本样式的那一列之前,标示该列的文件名称-i  #忽略字符大小写的差别-l  #列出文件内容符合指定的范本样式的文件名称-L  #列出文件内容不符合指定的范本样式的文件名称-n  #在显示符合范本样式的那一列之前,标示出该列的编号-q  #不显示任何信息-R/-r #此参数的效果和指定“-d recurse”参数相同-s  #不显示错误信息-v  #反转查找-V  #显示版本信息 -w  #只显示全字符合的列-x  #只显示全列符合的列-y  #此参数效果跟“-i”相同-o  #只输出文件中匹配到的部分正则表达式^  #匹配以XX开头的行$  #匹配以XX结尾的行

常用实例

1、在多个文件中查找:

grep "file" file_1 file_2 file_3

2、输出除之外的所有行 -v 选项:

grep -v "file" file_name

3、标记匹配颜色 --color=auto 选项:

grep "file" file_name --color=auto

4、使用正则表达式 -E 选项:

grep -E "[1-9]+"egrep "[1-9]+"

5、只输出文件中匹配到的部分 -o 选项:

echo this is a test line. | grep -o -E "[a-z]+."line.echo this is a test line. | egrep -o "[a-z]+."line.

6、统计文件或者文本中包含匹配字符串的行数-c 选项:

grep -c "text" file_name2

7、输出包含匹配字符串的行数 -n 选项:

grep "text" -n file_name或cat file_name | grep "text" -n

8、多个文件

grep "text" -n file_1 file_2

9、搜索多个文件并查找匹配文本在哪些文件中:

grep -l "text" file1 file2 file3...

10、grep递归搜索文件

在多级目录中对文本进行递归搜索:

grep "text" . -r -n

11、忽略匹配样式中的字符大小写:

echo "hello world" | grep -i "HELLO"hello

12、选项 -e 指定多个匹配样式:

echo this is a text line | grep -e "is" -e "line" -oisline

13、也可以使用 -f 选项来匹配多个样式,在样式文件中逐行写出需要匹配的字符。

cat patfileaaabbbecho aaa bbb ccc ddd eee | grep -f patfile -o

14、在grep搜索结果中包括或者排除指定文件:

只在目录中所有的.php和.html文件中递归搜索字符"main()"

grep "main()" . -r --include *.{php,html}

15、在搜索结果中排除所有README文件

grep "main()" . -r --exclude "README"

16、在搜索结果中排除filelist文件列表里的文件

grep "main()" . -r --exclude-from filelist

更多Linux命令请参考>>>值得收藏!Linux系统常用命令速查手册

Linux 三剑客命令实战操作

Grep实例介绍

grep "San" testfile #过滤有San的行grep '^J' testfile #显示以J开头的行grep '70$' testfile #显示以70结尾的行grep -v "834" testfile #显示所有不包括834的行grep ':12/' testfile #显示:12/的行 grep ':498-' testfile #显示:498-的行grep '[A-Z][a-z]{4}:[[:space:]][A-Z]' testfile #显示这样的行,一个大写字母+四个小写字母+空格+一个大写字母grep '[a-z]{1,}[[:space:]][Kk]' testfile #显示包括K k的行grep -n '[0-9]{6,}$' testfile #显示6位数字的行,并打印行号grep -i "lincoln" testfile #显示有lincoln的行,不区分大小写

Sed实例介绍

sed 's/Jon/Jonathan/g' testfile #全局替换(Jon替换成Jonathan)sed '1,3d' testfile #删除文件1-3行sed -n '5,10p' testfile #打印文件5-10行内容sed '/Lane/d' testfile #删除包包含lane的行sed -ne '/[1-9]{5}:1[12]/p' testfile #打印由5个数字+:11/12的行sed 's/^Fred/***&/' testfile #在以Fred开头的行前加上***sed -e 's/.*Jose.*/JOSE HAS RETIRE/g' testfile #将包含Jose的行替换成JOSE HAS RETIREsed -n '/^Popeye/p' testfile |sed 's/[0-9]{1,}/[0-9]{1,}/[0-9]{1,}/11/14/46/' #将以Popeye开头的行打印,然后将“数字/数字/数字”这格式的数字串替换成 11/14/46##pattern{n} 匹配模式出现n次。##pattern{n,} 匹配模式出现最少n次。##pattern{n,m} 匹配模式出现n到m次之间,n , m为0 - 2 5 5中任意整数sed '/^$/d' testfile #删除所有空行sed 's/.$//g' #删除以.结尾行sed 's/^[][]*//g' #删除行首空格sed 's//.[][]*/[]/g' #删除句号后跟两个或更多的空格,用一个空格代替sed 's/^.//g' #删除第一个字符sed 's/COL/(.../)//g' #删除紧跟COL的后三个字符sed 's/^////g' #删除路径中第一个/sed -n '3,/245700/'p testfile#从第三行开始查询到245700结束并打印sed -n '2,26!'p testfile#打印文件(除2-26)的行

Awk实例介绍

awk –F : ‘{print $2}’ datafile#以:分隔打印第二列awk –F : ‘/^Dan/{print $2}’ datafile#以:分隔打印以Dan开头行的第二列内容awk –F : ‘/^[CE]/{print $1}’ datafile #打印以C或E开头行的第一列awk –F : ‘{if(length($1) == 4) print $1}’ datafile #打印以:分隔且长度为4字符的第一列内容awk –F : ‘/[916]/{print $1}’ datafile#匹配916的行以:分隔打印第一列awk -F : '/^Vinh/{print "a"$5}' 2.txt#显示以Dan开头行并在第五列前加上aawk –F : ‘{print $2”,”$1}’  datafile#打印第二列第一列并以,分隔awk -F : '($5 == 68900) {print $1}' 2.txt#以:分隔打印第五列是68900的行第一列  awk -F : '{if(length($1) == 11) print $1}' 2.txt#打印以:分隔且长度为4字符的第一列内容awk -F : '$1~/Tommy Savage/ {print $5}' 2.txtawk -F : '($1 == "Tommy Savage") {print $5}' 2.txt#打印以:分隔且第一列为Tommy Savage的第五列内容ll |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ",size}'#统计目录个的文件所有的字节数awk 'BEGIN{size=0;} {size=size+$5;} END{print "[end]size is ",size/1024/1024,"M"}' #以M为单位显示目录下的所有字节数awk 'BEGIN{a=10;a+=10;print a}'20 #a+10等价于 a=a+10echo|awk 'BEGIN{a="100testaaa"}a~/test/{print "ok"}' #正则匹配a 是否有test字符,成立打印okawk 'BEGIN{a="b";print a=="b"?"ok":"err"}'okawk 'BEGIN{a="b";print a=="c"?"ok":"err"}'err#三目运算符?:awk '/root/{print $0}' passwd #匹配所有包含root的行awk -F: '$5~/root/{print $0}' passwd # 以分号作为分隔符,匹配第5个字段是root的行ifconfig eth0|awk 'BEGIN{FS="[[:space:]:]+"} NR==2{print $4}'#打印IP地址awk '{print toupper($0)}' test.txt#toupper是awk内置函数,将所小写字母转换成大写

Linux三剑客Awk、Sed、Grep 命令详解,到这里就介绍完了。欢迎评论、点赞、转发分享支持。

Linux 三剑客 Awk、Sed、Grep 命令详解

Linux 三剑客 Awk、Sed、Grep 命令详解

Linux 三剑客 Awk、Sed、Grep 命令详解

Linux 三剑客 Awk、Sed、Grep 命令详解

推荐阅读 点击标题可跳转

华为第一款台式机正式上线!

用了 10 年 Windows 后,我最终转向 Linux

从 lsof 开始,深入理解 Linux 虚拟文件系统

一款超牛逼的 Linux 终端复用神器(附安装、使用教程)

Linux 日志文件系统原来是这样工作的

超详细 116 页 Elasticsearch 实战文档!高清可下载

抓包工具 tcpdump 用法说明

Linux 系统多网卡环境下的路由配置

Linux 三剑客 Awk、Sed、Grep 命令详解

Linux 三剑客 Awk、Sed、Grep 命令详解

本文分享自微信公众号 - 民工哥技术之路(jishuroad)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这