Linux

正则表达式与文本编辑三剑客

一、基本正则表达式 BRE

字符类
.      任意单个字符
[ ]    中括号内任意单个字符
[^ ]   非中括号内任意单个字符

次数类
*      重复任意次
\{N\}  重复 N 次
\{N,\} 重复至少N次
\{,M\} 重复最多M次
\{N,M\}重复最少N次,最多M次

位置类
^     行首
$     行尾
\<    词首  \b
\>    词尾  \b

综合类
.*          任意个任意字符
^$          空行
^[ ]        以括号内的任意字符开头的行
^[^ ]       不以括号内的任意字符开头的行
[:alpha:]   所有的大小写字母
[:digit:]   所有的数字
[:upper:]   所有的大小字母
[:lower:]   所有的小写字母
[:space:]   所有的空白字符
[:punct:]   所有的符号
[:alnum:]   所有是数字和字母 [a-Z0-9]

\( \)       后项引用 \1

二、扩展正则表达式 ERE

+     至少1次
?     0或1次
{N}   重复N次
{N,}  最少N次
{,M}  最多M次
{N,M} 最少N次,最多M次
|     或
()    组字符  (my|your)self

三、Perl兼容正则表达式 PCRE

\d    匹配数字 [0-9]
\w    匹配字母数字下划线[a-zA-Z0-9_]
\s    匹配空格、制表符、换页符[\t\r\n]

文本编辑三剑客:grep、sed、awk

四、grep

grep是基于模式匹配行,默认使用基本正则表达式。

格式:grep [选项] 模式 [文件…]

常用的选项有:

-E  使用扩展正则表达式,等于egrep
-F  不使用正则表达式,等于fgrep
-G  使用基本正则表达式,默认值,等于grep
-P  使用Perl正则表达式

-v  反向查找,也就是不查找匹配的行
-i  忽略大小写
-o  只显示匹配的内容而不是行
-e  多条件匹配
-w  匹配完整的单词
-c  只显示匹配的行数
-m# 只匹配#hang
-q  静默模式

-A#  显示匹配行及其后#行
-B#  显示匹配行及其前#行
-C#  显示匹配行及其前后#行

常见的模式有:

'正则表达式'

grep三兄弟:

练习:

#匹配IP地址 
egrep '([0-9]{1,3}\.){3}[0-9]' 

五、sed

sed是流编辑器,可以从文件中一次读入(复制)一行进行编辑,然后把编辑后的结果输出到屏幕上。默认使用基本正则表达式。

命令格式:sed [选项] ‘ 表达式+动作 ‘ 文件……

常用的选项有:

-r  使用扩展正则表达式
-i  把编辑后的输出修改源文件
-n  关闭默认的输出
-e  多个编辑动作
-f  从脚本文件读取

常见的表达式有:

n              第n行
n,m            从第n行开始,第m行结束
n,m!           排查从第n行开始,第m行结束
/exp/          满足exp的行
/exp/,m        从第一个满足exp的行开始到第m行
n,/exp/        从第n行开始到第一个满足exp的行
/exp1/,/exp2/  从第一次满足exp1的行开始到第一个满足exp2的行

常见的动作:

p  打印
=  打印当前行行号
i  在该行前插入行
a  在该行后插入行
c  替换该行
s  查找替换 可以配合/g  支持后项引用 & 或者\1
d  删除行
r  当前行下读入文件内容
w  把该行另存为文件

练习:

1.  删除centos7系统/etc/grub2.cfg文件中所有以空白开头的行的行首的空白字符    
    sed -r 's/^[[:space:]]+//'
2.  删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行中的行首的#和空白字符   
    sed  -r 's/^#[[:space:]]+//'
3.  在centos6系统/root/install.log每一行行首增加#号  
    sed  's/^/#/'
4.  在/etc/fstab文件中不以#开头的行的行首增加#号   
    sed 's/^[^#]/#&/'
5.  处理/etc/fstab路径,使用sed命令取出其目录名和基名  
    echo "/etc/fstabl"|sed -n 's#/.*/##p'
    echo "/etc/fstabl"||sed -nr 's#(.*)/.*$#\1#p'
6.  利用sed 取出ifconfig命令中本机的IPv4地址  
    ifconfig | sed -nr 's/inet (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}).*broadcast.*/\1/p'
7.  统计centos安装光盘中Package目录下的所有rpm文件的以.分隔倒数第二个字段的重复次数 
    ls |sed -nr 's/.*\.(.*)\.rpm$/\1/p'|sort| uniq -c
8.  统计/etc/init.d/functions文件中每个单词的出现次数,并排序 (用grep和sed两种方法分别实现)   
    grep -oE '[a-Z]+' functions |sort | uniq -c | sort -n
    sed -nr 's/[[:punct:]]|[[:space:]]|[[:digit:]]/\n/gp' functions | grep -v '^$'| sort | uniq -c | sort -n

六、awk

语法:awk 选项 ‘BEGIN{动作};模式{动作};END{动作}’ 文件

常用选项:

-F  分隔符
-v  定义变量并赋值
-f  从脚本文件读取模式动作

常见模式:

默认支持扩展正则表达式
/正则表达式/        匹配正则表达式的行
比较表达式          满足比较表达式的行,可以使用数值或字符串的比较操作
pattern1, pattern2   表示从第一个匹配模式1的行开始到第一个匹配模式2的行结束

常见的动作:

print    默认动作打印所有列,多个动作需要使用;隔开
printf   格式化输出,默认行尾不行号  -左对齐  %-20d  数字变量  %s  字符变量
计算和赋值   可以进行数值计算和变量赋值,例如 sum += $1 。
条件判断   使用 if-else 结构根据条件执行不同的操作。

常见的内置变量:

$0       所有列
$1       第一列
$NF      最后一列
$(NF-1)  倒数第二列
NF       总列数
NR       当前行号
FS       输入分隔符,默认为空格
OFS      输出分隔符,默认为空格

样例:

1、只查看 ett.txt 文件(100 行)内第 20 到第 30 行的内容
	awk 'NR==20,NR==30'
2、[root@localhost tmp]# cat jflinux.txt
I am jflinux,myqq is 49000448
现在需要过滤 jflinux,49000448 字符串,请给出命令
	awk -F[,' '] '{print $3,$6}'
3、请执行命令取出 linux 中 eth0 的 IP 地址,只要 Ip,其他信息不要
	ifconfig eth0| awk '/\<inet\>/{print $2}' 
4、通过 APACHE 访问日志 access.log 统计 IP 和每个地址访问的次数,列出访问量前 10 名的 IP 地址,写出具
体命令
	awk '{print $1}' access_log-20231029 | sort |uniq -c | sort -rn | head

Leave a Reply