三剑客
sh -x 显示脚本执行过程
set命令设置开始debug和结束debug的位置 显示脚本执行过程,解决复杂脚本故障
正则(RE)表达式
应用场景
- 匹配有规律的:手机、身份证号、日志
规则
注意事项
- 所有的符号都是英文符号
- 通过grep 需加上引号
- 给grep、egrep加上颜色
alias grep='grep --color=auto' alias egrep='egrep --color=auto' - 注意系统的字符集:en_US.UTF-8,如果出现问题修改字符集为C export LANG=C
- 快速掌握正则:配合grep -o参数学习
正则符号
| 分类 | 符号 | 命令 |
|---|---|---|
| 基础正则BRE(basic RE) | ^ $ ^$ . \* .* [a-z] [^abc] | grep/sed/awk |
| 扩展正则ERE(Extended RE) | + | () {} ? | egrep(grep -E)/sed -r/awk |
基础正则
^:以…开头
grep '^My' oldboy.txt
$:以…结尾
grep '^My' oldboy.txt
cat -A file展示所有,末尾会显示$符号
^$:空行,这一行中没有任何内容(包括空格)
grep -n '^$' oldboy.txt
排除文件中的空行:grep -nv '^$' oldboy.txt
.:任意一个字符
grep '.' oldboy.txt
注意:.不会匹配空行
\:转义字符(脱掉马甲打回原形,去除原有特殊含义)
匹配以
.结尾的行
grep '\.$' oldboy.txt
- 转义字符序列
\n:回车换行\t:tab键
*:前一个字符连续出现0次或0次以上
grep '0*' oldboy.txt
.*:所有内容
grep '.*' oldboy.txt
注意:.*可以匹配出空行
匹配开始到is结束的内容:grep '^.*is' oldboy.txt
- 正则表达式的贪婪性:
.*表示所有或*连续出现的时候,表现出尽可能贪婪匹配
2*:数字2出现了0次或0次以上,如果2出现了0次,就相当于是没有匹配空字符
[]:[abc]----1次匹配1个字符,匹配任何一个字符(a或b或c),一般与+号搭配
grep '[abc]' oldboy.txt
grep -o '[abc]' oldboy.txt:显示匹配过程
- 精简写法:[a-z]、[A-Z]、[0-9]:
grep '[a-z]' oldboy.txt

- 不区分大小写写法1:
grep '[a-zA-Z0-9]' oldboy.txt

- 不区分大小写写法2:
grep -i '[a-z0-9]' oldboy.txt,-i表示不区分大小写

[]里面的内容去掉特殊含义
[a-z|A-Z|0-9]、[a-z,0-9]、[z-a 0-9]
里面|,,,空格 没有特殊特殊含义,仅表示匹配此字符
- **
[^]:表示取反,[^abc]表示排除a或b或c的内容
grep '[^abc]' oldboy.txt
扩展正则
+:前一个字符连续出现1次或1次以上,一般与[]搭配
grep只支持基础正则,使用扩展正则需要使用\符号
如:grep '0\+' oldboy.txt
一般扩展正则使用egrep或grep -E
- 匹配出文件中连续出现的数字:
egrep '[0-9]+' oldboy.txt- 匹配文件中的单词
egrep '[a-zA-Z]+' oldboy.txt
[]与|
| 符号 | 含义 | 应用场景 |
|---|---|---|
[] | 1次匹配1个字符[oldboy] | 匹配单个字符[]和+ |
| | 匹配1个字符或多个a|b|c oldboy|lidao | 匹配单词的时候 |
():被括起来的内容,表示一个整体(一个字符)或后向引用(反向引用sed)
egrep 'oldbo|ey' oldboy.txt
egrep 'oldb(o|e)y' oldboy.txt
egrep 'oldb[oe]y' oldboy.txt
{}:连续出现,o{n,m}前一个字母o至少出现n次,最多出现m次
egrep '0{1,3}' oldboy.txt
| 符号 | 释 义 | |
|---|---|---|
| o{n,m} | 前一个 字母o至少连续出现n次,最多出现m次 | >=n <=m |
| o{n } | 前一个 字母o连续出现n次 | ==n |
| o{n, } | 前一个 字母o至少连续出现n次 | >=n |
| o{,m} | 前一个 字母o最多连续出现m次 | <=m |
?:连续出现 前一个字符出现0次或1次
egrep 'go?d' oldboy.txt
正则实例
- 过滤出id.txt中符合要求的身份证号码
egrep '[0-9]{17}[0-9xX]' id.txt - 排除文件中的空行或含有#号的行
egrep -v '^$|#' id.txt
正则 VS 通配符
| 分类 | 用途 | 支持的命令 |
|---|---|---|
| 正则(re) | 三剑客、高级语言、进行过滤 | 三剑客grep、sed、awk、find、rename(ubuntu)、expr |
| 通配符 (pathname extension 或 glob) | 匹配文件(文件名)* .txt *.log{01…10} | linux大部分命令 |
三剑客
grep
用于过滤,grep过滤速度是最快的
| 选项 | 含义 |
|---|---|
-E | 等同于egrep 支持扩展正则 |
-A | after -A5匹配你要的内容并且显示接下来的5行 |
-B | before -B5匹配你要的内容并且显示上面的5行 |
-C | context -C5 匹配你要的内容并且显示上下5行 |
-c | line -c显示匹配到的内容的行数 类似于wc -l |
-v | 排除,取反(行)ps -ef | grep crond | grep -v grep |
-n | 显示行号 |
-I | 不区分大小写 |
-w | 精确匹配 |
\b | grep '\b abc \b'表示边界 等同于 grep -w 'abc' 、egrep '<abc>'、grep '\<abc\>' |
sed
替换、修改文件内容,取行,取出某个范围的内容(早上10:00到11:00)
- sed stream editor:流编辑器
- 格式
sed -r 's#oldboy#oldgirl#g' oldboy.txt
| 选项 | 功能 |
|---|---|
s | 替换substitute sub |
p | 显示print |
d | delete |
cai | 增加c/a/i |
-n | 取消默认输出 |
sed核心应用
- 查找
'1p'、'2p':指定行号进行查找,例:sed -n '3p' oldboy1.txt'1,5p':指定行号范围进行查找,例:sed -n '2,4p' oldboy1.txt'/lidao/p':类似于grep,过滤,//里面可以写正则,例:sed -n '/lidao/p' oldboy1.txt'/10:00/,/11:00/p':表示范围的过滤,例:sed -n '/101/,/103/p' oldboy1.txt'1,/yy/p':从某行开始,到匹配到某个字符结束,例:sed -n '1,/yy/p' oldboy1.txt
$表示最后一行,-n表示排除没匹配到的行
sed -n '4,$p' oldboy1.txt:4到最后一行
sed -n '$p' oldboy1.txt:最后一行,等同于tail -1 oldboy1.txt

- 过滤
sed -n '/[45]/p' oldboy1.txt
使用正则需要加上-r:sed -nr '/[0-9]{3}/p' oldboy1.txt
匹配成功的行数:sed -n '/16:44:57/,/16:47:35/p' test.log | wc -l
- 删除
'1d'、'2d':指定行号进行某行的删除,例:sed '3d' oldboy1.txt'1,5d':指定行号范围进行删除,例:sed '2,4d' oldboy1.txt'/lidao/d':匹配到字符的行删除,//里面可以写正则,例:sed '/lidao/d' oldboy1.txt'/10:00/,/11:00/d':表示范围的删除,例:sed '/101/,/103/d' oldboy1.txt'1,/yy/d':删除从某行开始,到匹配到某个字符结束,例:sed '1,/yy/d' oldboy1.txt
案例:删除文件的空行和包含#号的行
sed -r '/^$|#/d' /etc/ssh/sshd_config
!:表示取反
案例:不显示有空行和#号的行:sed -nr '/^$|#/!p' /etc/ssh/sshd_config
- aci
c:replace替换这行的内容,sed '3a \ 112,996 ' oldboy1.txt(Mac需要加一个\)
a:append追加,向指定的行或每一行追加内容,行后面
I:insert插入,向指定的行或每一行插入内容,行前面
案例:向文件中追加多行内容:
向sshd_config里面追加
UseDNS no
GSSAPIAUTCATION no
PermitRootLogin no
sed '$a \ UseDNS \ GSSAPIAUTCATION no \ PermitRootLogin no' sshd_config
- 替换:s
格式:
s###g
shell % sed 's#[0-9]#666#g' oldboy1.txt(sed默认只替换每行第一个匹配的内容,加g表示全局替换)
- 后向引用,反向引用
先保护,再使用
echo 123456 | sed -r 's#(.*)#<\1>#g'
echo oldboy_lidao | sed -r 's#^(.*)_(.*)$#\2_\1#g'(\1、\2表示位置)
案例:ip a 通过反向引用取出eth0网卡ip
stat /etc/hosts取出权限644
awk
取列,统计计算,对比,比较(>= <= != > <)
awk执行过程
awk中默认通过回车分割行,通过回车分割列
awk -F, 'BEGIN{print "name"}{print $2}END{print "end of file"}' oldboy1.txt

- awk读取前
awk -F、awk -v、BEGIN - awk读取文件时
{} - awk读取文件后
END
内置变量
取行
NR:NR==1取出某一行awk 'NR==1' oldboy1.txtNR>=1 && NR <=5取出1到5行(范围)awk 'NR>=1&&NR<=5' oldboy1.txt/oldboy/取出有某个字符的行awk '/oldboy/' oldboy1.txt/101/,/105/筛选范围awk '/101/,/105/' oldboy1.txt
取列
-F指定分割符awk -F, '{print $1}' oldboy1.txt$n取出某一列awk -F, '{print $2}' oldboy1.txt$0取出整行内容awk -F, '{print $0}' oldboy1.txtNF每行有多少列$NF表示取最后一列FS字段分隔符,每个字段结束标记OFS输出字段分隔符(awk显示每一列的时候,每一列通过什么分割,默认空格)awk -F, -vOFS=, '{print $NF $2 $1}' oldboy1.txtawk -F, '{print $1,$3}' oldboy1.txt | column -t(column -t表示对齐)
例:ifconfig | awk '/en1/,/active/' | awk -F"[ ]+" 'NR==5{print $2}'
awk 正则
~:包含
!~:不包含
^:某一列的开头$3~/^oldboy/
$:某一列的结尾$4~/lidao$/
^$:某一列是空的
- 第三列以1开头的行
sed -nr '/^#/!p' /etc/passwd | awk -F: '$3~/^1/'- 第三列以2开头的行,并显示第1列,第3列和最后一列
sed -nr '/^#/!p' /etc/passwd | awk -F: '$3~/^2/{print $1,$3,$NF}'
- 第三列以1或2开头的行,并显示第1列,第3列和最后一列
sed -nr '/^#/!p' /etc/passwd | awk -F: '$3~/^[12]/{print $1,$2,$NF}'
范围
//,//:从哪里开始到哪里结束
NR==1,NR==5:从第1行开始到第5行结束,类似于sed -n '1,5'p
显示指定范围内的ip地址
awk '/10:01:00/,/10:13:00/{print $1}' test.log
特殊模式:BEGIN{}和ENG{}
BEGIN{}:里面内容会在awk读取文件之前执行
1. 一般进行简单统计、计算,不涉及读取文件时
2. 处理文件之前,添加表头
3. 用来定义awk变量(很少用,可以用-v)
END{}:里面的内容会在awk读取文件之后执行
1. 统计,一般过程:现进行计算,最后END里面输出
2.awk使用数组,用来输出数组结果
END{}统计计算
统计方法
I++:计数,统计次数sum=sum+???:求和,累加array[]=array[]+1:array[]++数组分类计数
I、sum都是变量
例:统计oldboy.txt里面有多少个空行
awk '/^$/{i++}END{print i}' oldboy.txt
计算1到100的和
seq 100 | awk '{sum=sum+$1}END{print sum}'
查看过程
- awk数组
- 统计日志
- 统计次数:如统计每个ip出现次数、统计每种状态码出现次数、统计系统中每根用户被攻击的次数、统计攻击者ip出现次数、统计每个ip消耗的流量等
- 累加求和:统计每个ip消耗的流量
| 形式 | 使用 | 批量输出 | |
|---|---|---|---|
| sell数组 | array[0]=“oldboy” array[1]=“lidao” | echo ${array[0]} ${array[1]} | for i in ${array[*]} do echo $I done |
| awk数组 | array[0]=“oldboy” array[1]=“lidao” | print array[0] array[1] | for(i in array) print i(awk数组循环,变量获取的是数组的下标) |
awk 'BEGIN{a[0]="oldboy";a[1]="lidao";print a[0],a[1]}'

案例:处理以下文件内容,将域名取出并根据域名进行计数排序处理
awk -F"[/]+" '{array[$2]++}END{for(i in array)print i,array[i]}' test.txt
排序:awk -F"[/]+" '{array[$2]++}END{for(i in array)print i,array[i]}' test.txt|sort -rnk2
r:逆序,n:数字,k2:
统计状态码出现的次数
awk '$9~/[0-9]{3}/{array[$9]++}END{for(i in array)print i,array[i]}' test.log | sort -rnk2
统计每个ip消耗的流量
- for循环
awk 'BEGIN{for(i=1;i<=100;i++)sum+=i;print sum}'
- if
shell中:if[条件];then xxx else xxx fi
awk中:if(条件)xxx else xxx
df -h | awk -F"[ %]+" '{if($8>90)print "disk not enough"}'
⚠️awk使用多个条件的时候,第一个条件可以不放在不‘条件{动作}’,第二个条件一般使用if
统计单词字符数小于6的单词
awk -F"[ ]" '{for(i=1;i<=NF;i++) if(length($i)<6)print $i}'
本文介绍了正则表达式的基础和应用场景,包括匹配规则、注意事项和常见符号。接着详细讲解了Linux三剑客grep、sed和awk的用法。grep用于快速过滤,sed擅长内容替换和行操作,awk则用于数据处理和列取。文中还给出了丰富的实例和使用技巧。




















































7345

被折叠的 条评论
为什么被折叠?



