文章目录
1.正则表达式
- 正则表达式regular expression(RE),在Linux三剑客中应用可以实现大部分的操作
1.1正则表达是什么?与通配符区分
- 正则的作用:使用一些符号表达重复出现,大小写,开头/结尾含义
- 应用场景:过滤有规律的内容,尤其是日志、大量数据等
正则符号
分类 | |
---|---|
普通正则 | ^ $ ^$ . * .* [a-z] [^abc] |
扩展正则 | + () {} ? | |
区别:正则vs通配符
分类 | 诞生的目的 | 支持的命令 |
---|---|---|
正则 | 三剑客,高级语言,进行过滤 | 三剑客 |
通配符 | 匹配文件(文件名)*txt *log | Linux下面大部分命令都支持 |
1.2常用的正则表达式
基础正则 | |
---|---|
^ | 以……开头的 |
$ | 以……结尾的 |
^$ | 空行 |
. | 任意字符 |
* | 前一个字符连续出现0或者0次以上(重复) |
.* | 表示所有 |
\ | 转义字符 |
[] | 一个整体,匹配里面任意一个字符 |
[^] | 取反 |
0)创建一个名为sansan.txt 的文件
输入以下内容,用于实现后续的操作
$ cat sansan.txt
Hello,my name is sansan.
Hi,this is my space,you can read some articles writeen by sansan.
If these articles help you,please inspire me.
Thank you for reading.
1)^
以……开头的行
^Hello
以Hello开头的行
$ grep '^Hello' sansan.txt
Hello,my name is sansan.
2)$
以……结尾的行
sansan.$
以sansan.结尾的行
$ grep 'sansan.$' sansan.txt
Hello,my name is sansan.
Hi,this is my space,you can read some articles writeen by sansan.
3)^$
空行
- 空行,这一行中没有任何内容(空格也是符号)
- 排除文件中的空行
grep -v '^$' sansan.txt
(grep -v
指的是排除)
$ grep -v '^$' sansan.txt
Hello,my name is sansan.
Hi,this is my space,you can read some articles writeen by sansan.
If these articles help you,please inspire me.
Thank you for reading.
4) .
(点)任意一个字符
.
不匹配空行
5)*
前一个字符连续出现0次或0次以上
连续出现 san
(0出现一次)sansan
(连续出现两次)必须是连续的 sansan; *
很少单独使用
6).*
所有内容,任何内容,任意内容
- 整体记忆
.*
表示所有 - 了解:表示所有+*表示前一个字符出现多次 所有加起来就是所有的意思
^.*n
表示从头开始 中间为 .* 到n字母结束
$ grep ^.*n sansan.txt
注意: 正则特色:正则表达式的贪婪性。 .*
表示所有;*
连续出现的时候,表现出尽可能贪婪匹配。例如第一行中,虽然name中存在n,但是匹配并没有结束,而是匹配到最后的n为止。
7) \
转义字符:脱掉马甲打回原形,去除特殊含义
- 匹配出文件中以 .结尾的行
- 转义字符序列
- \n 回车换行
- \t tab键
8) []
[abc]
一次匹配一个字符 匹配任何一个字符(a或者b或者c)
每次只匹配一次,一行一行的匹配,从左到右
-
[a-z]匹配小写字母
-
[A-Z] 匹配大写的字母
-
[0-9]匹配数字
-
还可以连起来 [a-zA-Z0-9]
-
[a-Z]表示所有的大小写字符串 等同于
grep -i
不区分大小写
$ cat sansan.txt |grep '[abc]'
9)[^]
取反
[a-z | A-Z | 0-9]
匹配大小写字母和数字还匹配|- [] 中括号的所有字符都表示自己的例如
.
\
|
这些特殊的符号 [^]
取反==grep -v
(:这个留着你们自己探索呀~
1.3 扩展正则
符号 | |
---|---|
+ | 一个以及一个以上 |
| | 或者 |
() | 用小括号括起来,表示一个整体 |
{} | 前一个字母连续出现几次,可以具体到某一个数值,也可以是一个范围的指 |
? | 前一个字符出现0次或者1次 |
1)+
前一个字符连续出现1次或者1次以上
用egrep
或者用grep -E
- 匹配出文件中连续的数字或者单词
$ cat sansan.txt |egrep l+
$ cat sansan.txt |grep -E l+
2)|
或者
- grep grep ‘一个|另一个’ 当用它
[]
匹配不到了,可以考虑使用扩展中的 egrep的|
- 区别在于:[]一次只能匹配一个字符;
|
匹配一个字符或者是多个
例如:
需求一:匹配字符a b c,一次匹配一个字符
echo aaoaboaco |egrep "[abc]"
需求二:匹配字符串aao a b c,一次匹配一个字符或者多个字符
echo aaoaboaco |egrep "aao|a|b|c"
3)()
被括起来的内容,表示一个整体(一个字符)后向引用(反向引用)
sed命令:
- 被括起来的内容表示一个整体,在后边的sed中,发挥巨大的作用。如果这里不能理解就往后看sed的内容吧~~点击跳转
4){}
连续出现o{n,m} 前一个字母至少出现了n次,最多连续出现了m次
符号 | |
---|---|
o{n,m} | 至少出现n次最多出现m次 |
o{n} | 前一个字母o,连续出现n次 |
o{n,} | 前一个字母至少出现n次多了不限 |
o{,m} | 前一个字母最多出现m次,少了不限 |
$ egrep '(san){2}' sansan.txt
#()表示整体,{2}表示整体san连续出现2次
5)?
表示连续出现
前一个字符出现0次或者1次
(:这个就留这给你们自己试一下叭,就不放示例了哈~~
2.三剑客
:)正则的部分讲述完了,我们就把学到的正则和Linux的三剑客结合起来,体会到三剑客强大之处!!!
2.1三剑客特点及应用场景
命令 | 特点 | 场景 |
---|---|---|
grep | 过滤 | grep命令过滤速度是最快的 |
sed | 替换,修改文件内容,取行 | 进行替换,修改文件内容 取出某个范围的内容 |
awk | 取列,统计计算 | 取列 对比比较 >= <= != > < 统计计算 |
2.2三剑客——grep
在讲述正则的时候,一直都在用这个命令,现在来补充grep的其它参数:
选项 | 含义 |
---|---|
-E | ==egrep支持扩展正则 |
-A | after-A5匹配你要的内容显示接下来的5行 |
-B | before -B5 |
-C | context上下文 -C |
-c | 统计出现了多少行 类似于wc -l |
-v | 取反 |
-n | 显示行号 |
-i | 忽略大小写 |
-w | 精确匹配(精确到整个单词,不包含单词中存在的部分的单词) |
(:这几个参数比较简单,读者可以自行尝试哦~~
2.3三剑客——sed
2.3.1特点及格式
-
sed ——stream editor 流程编辑器,sed把文件内容当作是水,源源不断的进行处理,直到文件末尾
-
sed命令的格式,例如:
命令 选项 (s)sed命令功能(g)修饰符 参数 sed -r ‘s#sansan#ssaann#g’ 或者写做’s/sansan/ssaann/g’ sansan.txt
$ sed 's#sansan#ssaann#g' sansan.txt
Hello,my name is ssaann.
Hi,this is my space,you can read some articles writeen by ssaann.
If these articles help you,please inspire me.
Thank you for reading.
- sed命令核心功能,增删改查
功能 | 含义 |
---|---|
s | 替换 |
p | 显示 |
d | 删除 |
cai | 增加c/a/i |
2.3.2sed命令执行过程
- sed的功能总结为四个字“找谁干啥” 找谁:你要哪一行 干啥:增删、改查
- 首先根据正则等找到“谁”,然后指定他去干啥
2.3.3sed核心应用
1)查找某一行和某几行
查找格式 | |
---|---|
‘2p’ | 指定行号进行查找 ,查找第二行 |
‘1,3p’ ‘3,$p’ | 指定行号范围 显示从第四行到最后一行 |
‘/san/p’ | 类似于grep,过滤,//过滤的内容在里面 |
#显示第2行
$ sed -n '2p' sansan.txt
Hi,this is my space,you can read some articles writeen by sansan.
----------------------------------------------------------------------------
#显示1行到3行
$ sed -n '1,3p' sansan.txt
Hello,my name is sansan.
Hi,this is my space,you can read some articles writeen by sansan.
If these articles help you,please inspire me.
----------------------------------------------------------------------------
#显示3行到最后一行
$ sed -n '3,$p' sansan.txt
If these articles help you,please inspire me.
Thank you for reading.
----------------------------------------------------------------------------
#显示含有san的行
$ sed -n '/san/p' sansan.txt
Hello,my name is sansan.
Hi,this is my space,you can read some articles writeen by sansan.
2)过滤
sed -nr
表示 支持扩展正则
例如:
$ sed -nr '/[Hh]/p' sansan.txt
Hello,my name is sansan.
Hi,this is my space,you can read some articles writeen by sansan.
If these articles help you,please inspire me.
Thank you for reading.
$ sed -nr '/[l]{2}/p' sansan.txt
Hello,my name is sansan.
3)删除
例如:删除空行和#号的行 —— ^$
#
以下三种都可以实现,区分不同,灵活运用
$ egrep -v '^$|#' sansan.txt
#grep -v参数
$ sed -r 's/^$|#/d' sanssan.txt
# sed 删除d
$ sed -r 's/^$/|#/!p' sansan.txt
#sed 显示!p
4)增加
命令 | 例子 | |
---|---|---|
c | replace 替代这行的内容 | sed '1c HELLO' sansan.txt 第1行内容删除,行内容变成HELLO |
a | append追加,指向的行或每一行追加内容(行后面)>> | sed '1a HELLO' sansan.txt 第1行后添加一行,内容为HELLO |
i | insert 插入,向指定的行或每一行插入内容(行前面) | sed '2i HELLO' sansan.txt 第二2行前面添加一行,内容为 HELLO |
- 向文件中追加多行内容
#sed中c,替代
$ sed '1c HELLO' sansan.txt
HELLO
Hi,this is my space,you can read some articles writeen by sansan.
If these articles help you,please inspire me.
Thank you for reading.
----------------------------------------------------------------------------
#sed中a,追加
$ sed '1a HELLO' sansan.txt
Hello,my name is sansan.
HELLO
Hi,this is my space,you can read some articles writeen by sansan.
If these articles help you,please inspire me.
Thank you for reading.
----------------------------------------------------------------------------
#sed中i,插入
$ sed '2i HELLO' sansan.txt
Hello,my name is sansan.
HELLO
Hi,this is my space,you can read some articles writeen by sansan.
If these articles help you,please inspire me.
Thank you for reading.
5)替换
替换格式(任意的三个都可以)
sed###g
sed @@@g
sed ///g
#参考
$ sed 's#sansan#ssaann#g' sansan.txt
Hello,my name is ssaann.
Hi,this is my space,you can read some articles writeen by ssaann.
If these articles help you,please inspire me.
Thank you for reading.
-
g---->global 全局替换,sed默认只替换每一行中匹配的第一个
-
s----->substitue替换
6)后向引用,反向引用
口诀:先保护起来再使用
$ cat id.txt
lbr_D0
lbr_D15
lbr_D27
lbr_D51
UASB_D0
UASB_D14
UASB_D26
UASB_D50
$ sed -r 's#(.*)_(.*)#\1#g' id.txt
#先保护:用()保护你想要的部分,再使用:\1指的是取第一个小括号中的内容。
#这个例子把字符串根据"_"分为两个部分,想要哪部分在第二个和第三个#之间用"\1" "\2"的形式取出
lbr
lbr
lbr
lbr
UASB
UASB
UASB
UASB
$ sed -r 's#(.*)_(.*)#\2#g' id.txt
D0
D15
D27
D51
D0
D14
D26
D50
$ sed -r 's#(.*)_(.*)#\2_\1#g' id.txt
#还可以调换()中内容的顺序
D0_lbr
D15_lbr
D27_lbr
D51_lbr
D0_UASB
D14_UASB
D26_UASB
D50_UASB
2.4三剑客——awk
2.4.1awk的格式
awk 'BIGIN{}条件{}END{}' 文件名
awk的命令分为三个主体部分:
awk 读取文件之前BIGIN{}
awk读取文件时候 读取文件内容,判断,执行对应的命令,读取下一行
awk 读取文件之后 全部读取完后,会执行END{}中的内容
2.4.2awk命令执行过程
2.4.3awk取行,取列
名词 | awk中叫法 | 一些说明 |
---|---|---|
行 | 记录recored | 每一行默认是通过回车分隔的 |
列 | 字段field | 每一列默认是通过空格分隔的 |
awk中行和列结束标记都是可以修改的 | 自定义修改 -F -v FS |
1)取行
awk | |
---|---|
NR==1 | 取出某一行 |
NR>=1&&NR<=5 | 取出1到5行 |
/匹配的内容/ | 代替 sed 取行 |
/101/,/105/ | 101行到105行 |
符号 | > < >= <= != |
2)取列
- -F 指定分隔符 指定每一列结束标记 (默认是空格,连续的空格,和tab键)
- $数字,表示取出某一列,注意:再awk中@内容一个意思 表示取出某一列
- $0 表示 显示出整行的内容,整个字段的内容
- 取列的时候都是{print $0}
awk内置变量
内置变量 | |
---|---|
NR | Number of Record 记录号,行号 |
NF | Number of Field 每行有多少列 $NF表示最后一列 |
FS | -F: == -v FS=: 定义分割分为: Filed Separator 字段分隔符,每个字段结束标记 |
OFS | Output Filed Separator 输出字段分隔符 (awk显示每一列的时候,每一列之间通过什么分隔,默认为空格) |
$ cat /etc/passwd |head
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
$ awk -F: '{print $NF,$2,$3,$4,$5,$6,$1}' /etc/passwd |head
/bin/bash x 0 0 root /root root
/sbin/nologin x 1 1 bin /bin bin
/sbin/nologin x 2 2 daemon /sbin daemon
/sbin/nologin x 3 4 adm /var/adm adm
/sbin/nologin x 4 7 lp /var/spool/lpd lp
/bin/sync x 5 0 sync /sbin sync
/sbin/shutdown x 6 0 shutdown /sbin shutdown
/sbin/halt x 7 0 halt /sbin halt
/sbin/nologin x 8 12 mail /var/spool/mail mail
/sbin/nologin x 11 0 operator /root operator
例题:取出ip地址
$ ip a s enp4s0f0
2: enp4s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:e0:ec:34:3f:7e brd ff:ff:ff:ff:ff:ff
inet 192.168.1.216/22 brd 192.168.3.255 scope global enp4s0f0
valid_lft forever preferred_lft forever
inet6 fe80::2e0:ecff:fe34:3f7e/64 scope link
valid_lft forever preferred_lft forever
$ ip a s enp4s0f0 |awk -F"[ /]+" 'NR==3{print $3}'
192.168.1.216
#这个例子中,定义分割符为空格或者是/,(看图)可以知道ip地址位于第三行的第三列,则可以NR==3{print $3}输出,即可。
定义分割符为空格或者是/,可以知道ip地址位于第三行的第三列
2.4.4awk模式匹配
awk -F"[ /]+" ‘NR==3{print $3}’
awk | -F"[ /]+" | ‘NR==3{print $3}’ |
---|---|---|
命令 | 选项 | ‘条件{动作}’ ‘找谁{干啥}’ ‘pattern{action}’ |
- //支持扩展正则
- awk可以精确到某一列中包含/不包含……内容
#$3~ 表示第三列中包含 $3!~ 表示第三列中不包含
$ cat /etc/passwd | awk -F: -v OFS=: '$3~/^2/{print $1,$3,$NF}'
#以":"为分隔符,提取第三列中以2开头的行,打印出该行中的第一列第三列和最后一列
daemon:2:/sbin/nologin
postgres:26:/bin/bash
named:25:/sbin/nologin
mysql:27:/sbin/nologin
nscd:28:/sbin/nologin
rpcuser:29:/sbin/nologin
squid:23:/sbin/nologin
- 表示范围
- /哪里开始/,/哪里结束/ 常用
- NR1,NR5 从第一行到第五行结束,类似于sed -n ‘1,5p’
- 显示指定范围内的内容
2.4.5特殊条件 BEGIN{} END{}
模式 | 含义 | 应用场景 |
---|---|---|
BEGIN{} | 里面的内容会在awk在读取文件之前执行 | 1)进行简单的统计计算,不涉及读取文件(常见) 2)(了解)用于处理文件之前添加一个表头 |
END{} | 里面的内容会在awk读取文件之后执行官 | 1)awk进行统计,一般过程,先进行计算,最后END里输出结果 2)awk使用数组,用来输出数组结果 |
统计方法 | 可简写 | 应用场景 |
---|---|---|
i++ | i=i+1 | 统计次数 |
sum=sum+??? | sum+=??? | 累加求和 |
注意: i,sum 都是变量 |
# /etc/serivce 里面有多少空行
$ awk '/^$/{i++}END{print i}' /etc/services
17
# 累加求和
$ seq 100 |awk '{sum=sum+$1}END{print sum}'
5050
#显示累加的过程
$ seq 5 |awk '{sum=sum+$1;print sum}END{print sum}'
1
3
6
10
15
15
2.4.6awk数组
shell数组 | awk数组 | ||
---|---|---|---|
形式 | array[0]=oldboy array[1]=lidao | array[0]=oldboy array[1]=lidao | |
使用 | echo $(array[0]) | print array[0] | |
批量输出数组的内容 | for in ${array[*]} do echo$i done | for(i in array) print array[i] | awk数组专用循环,变量获取的是数组的下标,想要数组的内容a[i] |
$ awk 'BEGIN{a[0]="san";a[1]="sansan"; print a[0],a[1]}'
san sansan
$ awk 'BEGIN{a[0]="san";a[1]="sansan";a[3]=12306; for(i in a) print a[i]}'
san
sansan
12306
对于awk的学习是一个漫长的过程,awk命令本身就是一种语言,想要学好awk,需要不断地学习,才能掌握的透彻,现在的sansan只能掌握到这种水平,剩下的功能和用法留给读者和以后的我叭!!!
写到这里,本文就结束了,三剑客和正则的联合可以解决我对于生信分析的大部分的要求,值的反复观看学习呢~~~