Linux正则表达式以及三剑客grep、awk、sed等命令

Linux正则表达式以及三剑客 grepawksed 等命令

首先说为什么要学习这些东西呢?因为正则表达式和这三个命令功能太强大了,如果你要做一个运维人员,必须要完全掌握这三个命令,并且会熟练使用,才能让你的操作更加简单、高效,而作为普通使用Linux系统的人,正则表达式还是需要掌握的,因为每个语言都会有正则表达式,足以见得其重要性,而学习 grepawksed 这三个命令也会让你再使用Linux 系统的时候游刃有余,更加高效。接下来让我们开始吧

下文中命令的-v(查看版本)-h(帮助)这种通用选项就不做过多介绍了

1、正则表达式和通配符

为什么要先说正则表达式呢,因为后文的grepsedawk三种命令都是需要正则表达式的配合才可以发挥出其强大的功能。那就开始吧:

(1)正则表达式,在使用grep的时候需要grep -E或者egrep来进行调用

表达式含义实例
^^字符串,表示匹配以此字符串开头的一行^a:匹配以a开头的行
$字符串$,表示匹配以此字符串结尾的一行abc$:匹配以abc结尾的行
^$表示空行
.代表且只能代表任意一个字符a.c:表示a和c中间有一个字符
\转义符号,让有着特殊的字符显示本身,或者产生其他意思(元字符)\.:表示匹配点;\$表示匹配$
*匹配0个或多个前面一个字符a*:有0个a或任意个aaaaaa
?匹配0个或1个前面一个字符a?:有0个a或1个a
+匹配至少1个前面的字符a+:至少有1个a
.*匹配所有字符^.*:表示以任意多个字符开头;.*$,表示以任意多个字符结尾
[abc]匹配字符集合内的任意一个字符(单个字符而不是包含的单词)[a-z]:表示匹配小写字母;[a-zA-Z]:表示匹配所有字母
[^abc]匹配不包含^后的任意一个字符的内容(单个字符而不是包含的单词),上一行的去反像;其中括号里^此处为取反,注意和中括号内以^开头区别[^0-9]:表示不匹配数字
a{m,n}a连续出现的次数大于m次,小于n次,可以不写m或者n(逗号要写),意思应该都懂吧[abc]{2,}:表示连着的至少两个字符都是a或b或c
a{n}a连续出现n次,多了少了都不算[abc]{3}:表示连着三个字符都是a或b或c
|或,左右两边匹配到一个即可ab|bc:表示ab或bc有一个匹配到即可
()表示分组过滤a(b|d)c:表示要匹配abc或者adc

(2)元字符,在正则中使用

表达式含义
\b单词边界,比如\ba,能够匹配到以a开头的单词;\ba\b,只能够匹配到单词a
\B非单词边界,上面反之
\d单个数字字符,其和[0-9]也是有很大的区别的,推荐使用[0-9],\d可能无法达到预期结果
\D单个非数字字符,上面反之
\w单个单词字符(字母,数字与_),比如\w{6,10},能够匹配到一个简单的密码
\W单个非单词字符,上面反之
\s单个空白字符,普通空格、tab键(\t)都可以匹配到
\S单个非空白字符,上面反之
\n换行符
\r回车
\t横向制表符
\v垂直制表符
\f换页符

(3)通配符,文件名、普通命令都可以使用

通配符含义
.当前目录
两个点代表上一级目录
*通配符,代表所有(0到多个)字符,例如“*.txt”,找出所有的txt文件
通配符,代表1个字符,例如“???.txt”,找出名字是4个字符的txt文件
~当前用户的home目录
-上一次所在的目录(路径),cd命令之前的目录
/路径分隔符号,也是根目录的意思
连续不同命令的分隔符(两个命令的分隔符)
#配置文件注释(就是让其命令失效,但可以给管理员看到)
|管道
$变量前需要加的符号,例如“echo $LANG”,可以打印出当前命令窗口的字符集
>>追加重定向,追加内容文件尾部
<<追加输入重定向
`tab键上面的键,反引号,两个``中间的命令,会先执行

(4)简单举个例子吧:

① 匹配ip地址:^([0-9]{1,3}\.){3}[0-9]{1,3}$ # 以数字显示1-3次,然后是点循环3次开头,再数字显示1-3次结尾。

2、grep命令

(1)其语法格式

grep [选项] "正则字符串" 文件目录

当然,[选项]也可以放到命令的最后

(2)其中[选项]的参数可以是

选项作用意义
-r当文件目录参数是文件夹时,必须使用该选项,用来遍历文件夹下的所有文件
-n输出时显示行号
-v反向,输出匹配到的行以外的行,即输出所有不匹配的行
-c只输出匹配到的行数
-i忽略大小写
-l输出所有匹配到字符串的的文件名
-x完全匹配字符串,空格不匹配也不行
-A数字显示匹配到的行以及这行后面的n行(n即是你写的数字,此数字必写,可以为0)
-B数字显示匹配到的行以及这行前面的n行(n即是你写的数字,此数字必写,可以为0)
-C数字显示匹配到的行以及这行前后的n行(n即是你写的数字,此数字必写,可以为0)

(3)这个命令并不难(其格式就是上面这种比较固定),但我们还是来举个例子吧

先来准备个文件吧:

wtq@wtq[~]$ cat -n test.txt
1	#!/bin/sh
2	# 读取文件最后一行的四种方式
3	# cat suv.mnc | awk 'END {print}'
4	# cat 343/asd/kbc/text.txt | sed -n '$p'
5	# cat /home/wtq/asd.mnc | sed '$!N;$!D'
6	# cat bbb.suv | awk '{b=a"\n"$0;a=$0}END{print b}'
7	#sudo dpkg-reconfigure dashsh end

① 找到包含“end”的行,忽略其大小写,并显示行号:

wtq@wtq[~]$ grep -in "end" test.txt 	# n表示输出行号,i表示忽略大小写
3:# cat suv.mnc | awk 'END {print}'
6:# cat bbb.suv | awk '{b=a"\n"$0;a=$0}END{print b}'
7:#sudo dpkg-reconfigure dashsh end

② 不包含“cat”的行,只显示其行数:

wtq@wtq[~]$ grep "cat" test.txt -v 		# 选项也可以放在结尾,v表示反转,不包含
#!/bin/sh
# 读取文件最后一行的四种方式
#sudo dpkg-reconfigure dashsh end
wtq@wtq[~]$ grep "cat" test.txt -vc		# c表示只输出结果的总行数
3

③ 用正则进行搜索:

先来匹配出宝行“d”、“k”,中间有且只有一个随意字符的行:

wtq@wtq[~]$ grep -n "d.k" test.txt 			# 不使用-E的时候, .表示通配符,匹配任意一个字符
4:# cat 343/asd/kbc/text.txt | sed -n '$p'
7:#sudo dpkg-reconfigure dashsh end

再来匹配出“ }‘ ”结尾的行,显示其行号

wtq@wtq[~]$ grep -nE "}'$" test.txt 		# $表示以什么结尾
3:# cat suv.mnc | awk 'END {print}'
6:# cat bbb.suv | awk '{b=a"\n"$0;a=$0}END{print b}'

④ 遍历SDK目录下,找出其所有的“config”:

wtq@wtq[~/Android/Sdk]$ grep "config" ./ -rn	# 由于结果太多我就不输出了,大家可以自己试一下

其他的:

1、egrep命令

其用法同grep -Eegrep是用extended regular expression(拓展的正则表达式)语法来解读的,而grep则用basic regular expression(基本的正则表达式子) 语法解读,extended regular expressionbasic regular expression的表达更规范。

2、fgrep命令

其用法同grep -F,可以当作是其的简写,不常用。

3、rgrep命令

用于递归查找文件夹下所有的子文件中符合条件的字符串,同grep -r

3、sed命令

(1)其语法格式为

sed [选项] [脚本/脚本文件] 文本文件

当然,[选项]也可以放到命令的最后

其中[选项]的参数可以是

选项作用意义
-e表示第三个位置跟的是脚本命令,可以写多个(一般情况下可以省略)
-f表示第三个位置跟的是脚本文件
-n表示只显示脚本处理之后的结果,不写的会把全部内容打印一次,而搜索结果的行会显示两行
-i直接修改文件内容

(2)那脚本怎么写呢?

① "/正则表达式/ 动作"
② "行号m,行号n 动作"
③ sed "s/要被取代的字串/新的字串/g"

我们一种一种来说啊

①第一种和第二种这里面的动作是什么?

动作作用意义
行号a字符串a表示append,表示在你输入的行号n的下一行插入一句字符串
行号i字符串i表示insert,表示在你输入的行号n的上一行插入一句字符串
c字符串c表示change,表示将匹配到的(一般在2中使用)
dd表示delete,删除匹配到的行
pp表示print,打印匹配到的行,一般与-n配合
ss表示search&replace,表示搜索出匹配的字符串并且将之替换(一般在③中使用)
gg表示global,g 代表全部替代匹配到的内容(一般在③中使用)

②其实第一种和第二种差不多,只是第一种正则只能一行一行的匹配其中内容,而第二种可以从m行到n行一起进行处理,所以在会使用第一种就会使用第二种了。这两种都是针对行进行处理,匹配到的结果都是包含这个字符串的一整行。

③除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的搜寻并取代。而这第三种就是针对部分数据进行搜索替换,意为匹配到的字符串后,使用新的字符串将之替换,不会修改文件内容,只会替换显示结果。因此我们可以结合前两种方式,在选择的行中替换匹配到的字符串。

(3)上述说了这么多,大家肯定也是一脸懵,说再多也没有举例子来的真实,接下来就是举例子环节了。

首先我们准备一个文件:

wtq@wtq[~]$ cat test.txt -n
1	 auu 
2	 aeeeeeee
3	 se 
4	 sdddd 
5	 ooaekkaemmae+ 
6	 kka 
7	 aeaekk

① 在第四行后面加一个”ashdjk“,为了方便显示我就使用另一种方式了:

wtq@wtq[~]$ cat test.txt -n | sed "4a ashdjk"   # 4表示第四行,a表示第四行之后添加,空格之后的字符串表示要添加的字符串
1	auu 
2	aeeeeeee
3	se 
4	sdddd 
ashdjk
5	ooaekkaemmae+ 
6	kka 
7	aeaekk

那在第四行之后,其用法都是一样的,大家可以自行练习试用一下(比如再第五行之前插入”welcome you!“)

② 删除3至5行的内容:

wtq@wtq[~]$ cat test.txt -n | sed "3,5d"  # m,n表示从3行到5行的内容,d表示删除
1	auu 
2	aeeeeeee
6	kka 
7	aeaekk

那删除3行以后的内容呢,我从不能去数一数总共有几行吧:

wtq@wtq[~]$ cat test.txt -n | sed "3,$ d"    # $表示结尾,为了避免$与d产生问题,因此中间加个空格
1	auu 
2	aeeeeeee

(那我想删除3行以前的内容,应该怎么做呢?)

③ 找到所有”ae“字符串,将之替换为”new“:

wtq@wtq[~]$ cat test.txt -n | sed "/ae/c new"
1	auu 
new
3	se 
4	sdddd 
new
6	kka 
new

当我们使用第一种脚本的c的时候,发现其替换了包含这个字符串的整行。前文也说了,第一、二种脚本都是针对行进行处理,而且c更多的时候使用在第二种脚本之中。因此我们应该使用第三种脚本方式才行完成这个功能:

wtq@wtq[~]$ cat test.txt -n | sed "s/ae/new/g"    # s表示搜索替换,前一个//表示需要搜索的字符串,后一个//表示需要替换为的字符串,g表示全局搜索
1	auu 
2	neweeeeee
3	se 
4	sdddd 
5	oonewkknewmmnew+ 
6	kka 
7	newnewkk

(那将第2行至第3行替换为”i an boy“,应该怎么写呢?)

④ 只打印出3行至5行的内容:

wtq@wtq[~]$ cat test.txt -n | sed "3,5 p"	  # p表示打印
1	auu 
2	aeeeeeee
3	se 
3	se 
4	sdddd 
4	sdddd 
5	ooaekkaemmae+ 
5	ooaekkaemmae+ 
6	kka 
7	aeaekk

并没有打印出我们想要的结果,它全部打印了一遍,只是把3行至5行多打印了一次,值得注意的是,这个p需要配合-n使用,才能打印出我们想要的效果:

wtq@wtq[~]$ cat test.txt -n | sed -n "3,5 p"	# -n表示只打印匹配到的结果
3	se 
4	sdddd 
5	ooaekkaemmae+

(那只打印所有具有”ae“的行,应该怎么写呢?)

⑤ 替换5行至6行中共的”kk“,将之替换为”new“:

wtq@wtq[~]$ cat test.txt -n | sed "5,6{s/kk/new/g}"    # 这是一个组合操作,找到5行和6行之后是一个组合操作,不是单一的p或者d等等,因此需要使用{},其中进行替换操作
1	auu 
2	aeeeeeee
3	se 
4	sdddd 
5	ooaenewaemmae+ 
6	newa 
7	aeaekk		#第七行的kk并未替换

/sbin/ifconfig命令可以获取到本地得IP地址,其中inet addr:就是本机的地址,我们可以通过sed命令来只输出本机的地址:

wtq@wtq[~]/sbin/ifconfig
enp0s31f6 Link encap:Ethernet  HWaddr 30:9c:23:77:5f:ed  
          inet addr:192.168.0.109  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::b060:e7f5:b451:e814/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2046238 errors:0 dropped:0 overruns:0 frame:0
          TX packets:712812 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1260925614 (1.2 GB)  TX bytes:121332377 (121.3 MB)
          Interrupt:16 Memory:f7100000-f7120000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:44336 errors:0 dropped:0 overruns:0 frame:0
          TX packets:44336 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:10535833 (10.5 MB)  TX bytes:10535833 (10.5 MB)

wtq@wtq[~]$ /sbin/ifconfig | sed -n "/inet addr/p" | sed -n "1p" | sed "s/^.*addr://g" | sed "s/  Bcast.*$//g"    #第一次找出包含"inet addr"的行;第二次筛去127.0.0.1的地址;第三次将"开头到addr:"替换为"",即删除;第四次将  "Bcast到结尾"的字符串删除
192.168.0.109

⑦ 修改文件,删除第一行的内容:

wtq@wtq[~]$ sed -i "1,1d" test.txt   # -i表示修改文件内容(不建议使用)
wtq@wtq[~]$ cat -n test.txt 
1	aeeeeeee
2	se 
3	sdddd 
4	ooaekkaemmae+ 
5	kka 
6	aeaekk

⑧ 最后来一个看起来比较复杂但其实相对简单的: df -h可以查看本机的磁盘容量,查找出其中的"/dev/"开头的行,整行替换为”this is new line“

wtq@wtq[~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            7.8G     0  7.8G   0% /dev
tmpfs           1.6G  9.6M  1.6G   1% /run
/dev/nvme0n1p1   46G  5.9G   38G  14% /
tmpfs           7.8G  2.0M  7.8G   1% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
/dev/nvme0n1p6  4.5G  147M  4.1G   4% /boot
/dev/nvme0n1p7  390G   61G  309G  17% /home
/dev/sda1       1.8T  932G  809G  54% /mnt/disk2
tmpfs           1.6G   80K  1.6G   1% /run/user/1000

wtq@wtq[~]$ df -h | sed "/^\/dev\//c this is new line"    # 这次就自己分析一下怎么实现的吧
Filesystem      Size  Used Avail Use% Mounted on
udev            7.8G     0  7.8G   0% /dev
tmpfs           1.6G  9.6M  1.6G   1% /run
this is new line
tmpfs           7.8G  1.9M  7.8G   1% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
this is new line
this is new line
this is new line
tmpfs           1.6G   80K  1.6G   1% /run/user/1000
4、awk命令

最后这个命令相较于上面两个是比较难的一个。对于awk命令,我在网上也找了很多,很多自己写的不全面也不 易懂,本文主要参照菜鸟教程中对这个命令的描述来进行讲解,通过阅读其资料,来参照自己的方式,来进行阐述。这个命令主要作用是循环遍历每一行数据,对每一行,先使用分隔符(默认空格)进行切分成列,再对列进行处理。使用此命令需要先掌握print命令,其中printf类似于C语言中的printf。当然,下文在使用print命令的时候,也会给大家注释

(1)其语法格式为:

awk [选项] [脚本/脚本文件] 文本文件

其中脚本的格式为(其中选项、begin{}、end{}、文本文件等部分不需要的时候都可以省略):

BEGIN { 循环所有行之前的处理(变量的声明) }
{ 循环处理每一行的命令 }
END { 循环所有行之后的处理事情 }

(2)都有哪些选项呢(这里列举一些比较常用的)?

选项作用意义
-F分割符指定分隔符,可以使用多个分隔符,”-F [多个分隔符]“,越靠前的分隔符优先级越高
-v 变量=值给变量赋值,可以加多个-v来给多个变量赋值
-f读取脚本文件

(3)接下来就匆匆的进入例子环节了,有什么补充的在例子中进行补充了(_)。

按照惯例,我们先准备一个文件:

wtq@wtq[~]$ cat test.txt       #这里不打印行号了,因为行号不重要,awk命令是会循环处理每一行
number this is a apple
50 This's a dog
20 a,b,c asd
jh,adf sd dsa
21 asdkj asd, asd
10 adfds'daf,abc

① 使用空格分割,显示第1列和第3列:

wtq@wtq[~]$ awk '{print $1,$3}' test.txt    # 注意,这里不能使用双引号,默认分隔符是空格,因此可以不写,而"$数字"表示第几列
number is
50 a
20 asd
jh,adf dsa
21 asd,
10 				# 由于最后一行用空格分割只有两列,因此第三列为空

那想使用”,“进行分割呢?显示第1列和第2列,然后我们为了方便显示观看,我们使用格式进行输出:

wtq@wtq[~]$ cat test.txt | awk -F, '{printf "%-25s %-15s\n",$1,$2}'   # 使用-F就可以指定分割符了,printf的格式中,%s表示显示字符串,中间的-表示居左,数字25和15表示总共占多少个字符,需要注意的是%和$的数量要对应(和C语言的printf是一样的)
number this is a apple              
50 This's a dog                     
20 a                      b         
jh                        adf sd dsa
21 asdkj asd               asd      	# 这个分割以后asd前面还有个空格,因此会比较突出
10 adfds'daf              abc 

再来,我想用空格和”,“两种进行分割呢?显示第1列和第2列:

wtq@wtq[~]$ awk -F '[ ,]' '{printf "%-10s %15s\n",$1,$2}' test.txt  #自己分析一下现象产生的原因吧
number                this
50                  This's
20                       a
jh                     adf
21                   asdkj
10               adfds'daf

② 使用空格分割,设置默认值a=1,我想显示第一列、第一列的值都加上这个默认值以及第三列:

wtq@wtq[~]$ awk -va=1 '{printf "%-10s %-4d %-10s\n",$1,$1+1,$3}' test.txt  # -v用来设置默认值,后面加表达式,因此在后面的printf种可以直接使用a,,,%d表示数字
number     1    is        	# 当值为字符串时,其值相当于0,再进行加法运算
50         51   a         	# 当值为数字时,则直接进行加法运算
20         21   asd       
jh,adf     1    dsa       
21         22   asd,      
10         11             

同样的,使用空格分割,设置默认值a=1,b=2, s=s,我只想显示第一列+s和a+b:

wtq@wtq[~]$ awk -va=1 -vb=2 -vs=s '{printf "%-25s %d\n",$1s,a+b}' test.txt
numbers                   3
50s                       3
20s                       3
jh,adfs                   3
21s                       3
10s                       3

如果开始不赋值,其都默认值,$1+a的时候,a默认为0,$1a的时候,a默认为”“,因此不赋值也不会报错,你懂了吗?

③ 接下来就是运算符了,运算符大家应该用的比较多了,各个语言的运算符基本上都相同,这里列举几个不同的需要注意的吧

运算符描述
+、-、*、/、%、=、+=、-=、*=、/=、%=、^=、**=、++、–、<、<=、>、>=、!=、==、&&、||、!、常用运算,不做描述
~ 和 !~匹配正则表达式和不匹配正则表达式
?:三元运算符,if?a:b,if为真返回a,表示if为假返回b
空格连接
^ ***求幂
$字段引用
in数组成员,a in b,表示a是否是b的一部分

其实不难看出大部分都比较常用的,需要记得也没几个。那我们看看怎么用吧

默认分割的列,找出第一列大于20的:

wtq@wtq[~]$ awk '$1>20' test.txt 
number this is a apple   # 不难看出字符串不参与比较,直接显示
50 This's a dog
jh,adf sd dsa
21 asdkj asd, asd

默认分割的列,找出第一列大于20的,只显示第一行和第三行:

wtq@wtq[~]$ awk '$1>20 {print $1,$3}' test.txt 			# 很简单吧
number is
50 a
jh,adf dsa
21 asd,

④ 先来把脚本的格式来阐述一下:

wtq@wtq[~]$ awk 'BEGIN{ print "--------------" }{printf "%-10s %-10s\n",$2,$3} END{print "--------------"}' test.txt   # 三个中括号,表示三个节点,注意:BEGIN和END必须要写,不写你试试会发生什么?
--------------
this       is        
This's     a         
a,b,c      asd       
sd         dsa       
asdkj      asd,      
adfds'daf,abc           
--------------

我们也可以把这个脚本写到一个文件(文件后缀类型随意)中,脚本可以写成多行,方便自己阅读,通过-f来调用脚本文件,使得更方便:

wtq@wtq[~]$ cat aaa.txt				#其中的格式自己可以调整,不必只显示一行,方便自己阅读
BEGIN{ print "--------------" }
{printf "%-10s %-10s\n",$2,$3}
END{print "--------------"}
wtq@wtq[~]$ awk -f aaa.txt test.txt 		# 更简洁明了
--------------
this       is        
This's     a         
a,b,c      asd       
sd         dsa       
asdkj      asd,      
adfds'daf,abc           
--------------

⑤ 接下来是内建变量,就是不需要使用-v去声明的变量

变量描述
$0完整的输入记录
ARGC命令行参数的数目
ARGIND命令行中当前文件的位置(从0开始算)
ARGV包含命令行参数的数组
CONVFMT数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO最后一个系统错误的描述
FIELDWIDTHS字段宽度列表(用空格键分隔)
FILENAME当前文件名
FNR各文件分别计数的行号
FS字段分隔符(默认是任何空格)
IGNORECASE如果为真,则进行忽略大小写的匹配
NF一条记录的字段的数目
NR已经读出的记录数,就是行号,从1开始
OFMT数字的输出格式(默认值是%.6g)
OFS输出记录分隔符(输出换行符),输出时用指定的符号代替换行符
ORS输出记录分隔符(默认值是一个换行符)
RLENGTH由match函数所匹配的字符串的长度
RS记录分隔符(默认是一个换行符)
RSTART由match函数所匹配的字符串的第一个位置
SUBSEP数组下标分隔符(默认值是/034)

来用一下吧:

wtq@wtq[~]$ 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	# OFS默认为空格,ORS、RS默认为换行,因此会有两个空行,这些内建变量的意思自己看吧
---------------------------------------------
test.txt    2    1         5    1         
    

test.txt    2    2         4    2         
    

test.txt    2    3         3    3         
    

test.txt    2    4         3    4         
    

test.txt    2    5         4    5         
    

test.txt    2    6         2    6         
    

使用空格分割,显示行号、第1列和第3列,其输出使用"_"进行分割:

wtq@wtq[~]$ awk '{print FNR,$1,$3}' OFS="_" test.txt 	# 这个还是比较简单吧
1_number_is
2_50_a
3_20_asd
4_jh,adf_dsa
5_21_asd,
6_10_

⑥ 接下来就正则了,不使用正则表达式,命令都没有灵魂,哈哈哈哈

先来找一下默认分割下,第2列中含有ad的行,显示行号、第2列和第3列

wtq@wtq[~]$ awk '$2 ~ /ad/ {print FNR,$2,$3}' test.txt
6 adfds'daf,abc

这个例子不好用正则,也之前也用了那么多的正则,大家自己练习一下吧

⑦ 最后来一个比较有趣的例子吧,seq命令可以打印连续数字,seq 9可以打印出1到9的数字,因此我们使用它来打印九九乘法表

wtq@wtq[~]$ seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'       # 大家可以自行分析一下,(其实sed 'H;g'我也还没搞懂)
1x1=1
1x2=2	2x2=4
1x3=3	2x3=6	3x3=9
1x4=4	2x4=8	3x4=12	4x4=16
1x5=5	2x5=10	3x5=15	4x5=20	5x5=25
1x6=6	2x6=12	3x6=18	4x6=24	5x6=30	6x6=36
1x7=7	2x7=14	3x7=21	4x7=28	5x7=35	6x7=42	7x7=49
1x8=8	2x8=16	3x8=24	4x8=32	5x8=40	6x8=48	7x8=56	8x8=64
1x9=9	2x9=18	3x9=27	4x9=36	5x9=45	6x9=54	7x9=63	8x9=72	9x9=81

Linux 正则表达式以及三剑客 grepawksed 等命令,目前就收罗这么多,当发现新的内容的时候,我也会随时更新博客,欢迎大家评论留言

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值