正则表达式定义
-
正则表达式,又称正则表达式、常规表达式
-
使用字符串来描述、匹配一系列符合某个规则的字符串
-
正则表达式组成
- 普通字符
大小写字母、数字、标点符号及一些其他符号 - 元字符
在正则表达式中具有特殊意义的专用字符
- 普通字符
-
正则表达式层次
- 基础正则表达式
- 扩张正则表达式
-
linux中文本处理文具
grep
egrep
sed
awk
基础正则表达式元字符
- 基础正则表达式即常用的正则表达式部分
- 除了普通字符外,常见的以下元字符
\ :转义符;\n:换行;!:非
^:匹配以...开头
$:匹配以...结尾
^$:匹配空格
.:匹配出\n(换行)之外的任意的一个字符
*:取决于前面一个字符,代表前面一个字符0次或多次
.*:任意长度的字符,*取决于.的字符
[ ]:匹配指定范围内的单个或多个字符
[^]:匹配任意不在列表中的单个或一组字符;是区分大小写的
^[]:匹配指定范围内的单个或多个字符开头
^[^]:匹配任意不在列表中的单个或一组字符
\{n\}:匹配前面的字符出现n次
\{n,\}:匹配前面的字符至少n次
\{,m\}:匹配前一个字符最多出现m次
\{n,m}:匹配前面的字符n到m次
\< :匹配以....开头的行
\> :匹配以....结尾的行
\<......\>:匹配某一个单词的行;精确匹配
grep+egrep
grep是一种强大的文本搜索工具,它能使用特定模式匹配(包括正则表达式)搜索文本,并默认输出匹配行。Unix的grep家族包括grep、egrep和fgrep
linux使用GNU版本的grep。它功能更强,它也可以通过-E命令行选项来使用egrep功能
举例
1、查找不以大写字母开头的行(三种写法)。
grep '^[^A-Z]' 2.txt
grep -v '^[A-Z]' 2.txt
grep '^[^[:upper:]]' 2.txt
2、查找有数字的行(两种写法)
grep '[0-9]' 2.txt
grep -P '\d' 2.txt
3、查找一个数字和一个字母连起来的
grep -E '[0-9][a-zA-Z]|[a-zA-Z][0-9]' 2.txt
4、查找不以r开头的行
grep -v '^r' 2.txt
grep '^[^r]' 2.txt
5、查找以数字开头的
grep '^[0-9]' 2.txt
6、查找以大写字母开头的
grep '^[A-Z]' 2.txt
7、查找以小写字母开头的
grep '^[a-z]' 2.txt
8、查找以点结束的
grep '\.$' 2.txt
9、去掉空行
grep -v '^$' 2.txt
10、查找完全匹配abc的行
grep '\<abc\>' 2.txt
11、查找A后有三个数字的行
grep -E 'A[0-9]{3}' 2.txt
grep 'A[0-9]\{3\}' 2.txt
12、统计root在/etc/passwd里出现了几次
grep -o 'root' 1.txt |wc -l
13、用正则表达式找出自己的IP地址、广播地址、子网掩码
ifconfig eth0|grep Bcast|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
ifconfig eth0|grep Bcast| grep -E -o '([0-9]{1,3}.){3}[0-9]{1,3}'
ifconfig eth0|grep Bcast| grep -P -o '\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}'
ifconfig eth0|grep Bcast| grep -P -o '(\d{1,3}.){3}\d{1,3}'
ifconfig eth0|grep Bcast| grep -P -o '(\d+.){3}\d+'
# egrep --color '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-eth0
IPADDR=10.1.1.1
NETMASK=255.255.255.0
GATEWAY=10.1.1.254
# egrep --color '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /etc/sysconfig/network-scripts/ifcfg-eth0
IPADDR=10.1.1.1
NETMASK=255.255.255.0
GATEWAY=10.1.1.254
14、找出文件中的ip地址并且打印替换成172.16.2.254
grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt |sed -n 's/192.168.0.\(254\)/172.16.2.\1/p'
15、找出文件中的ip地址
grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt
16、找出全部是数字的行
grep -E '^[0-9]+$' test
17、找出邮箱地址
grep -E '^[0-9]+@[a-z0-9]+\.[a-z]+$'
grep --help:
匹配模式选择:
Regexp selection and interpretation:
-E, --extended-regexp 扩展正则
-G, --basic-regexp 基本正则
-P, --perl-regexp 调用perl的正则
-e, --regexp=PATTERN use PATTERN for matching
-f, --file=FILE obtain PATTERN from FILE
-i, --ignore-case 忽略大小写
-w, --word-regexp 匹配整个单词
Sed工具概述
- 文本处理工具,读取文本内容,根据指定的条件进行处理,如删除、替换、增加等
- 可在无交互的情况下实现相当复杂的文本处理操作
- 被广泛应用于Shell脚本,以完成自动化处理任务
- sed依赖于正则表达式
- 工作原理
读入新的一行内容到缓存空间;
从指定的操作指令中取出第一条指令,判断是否匹配pattern;
如果不匹配,则忽略后续的编辑命令,回到第2步继续取出下一条指令;
如果匹配,则针对缓存的行执行后续的编辑命令;完成后,回到第2步继续取出下一条指令;
当所有指令都应用之后,输出缓存行的内容;回到第1步继续读入下一行内容;
当所有行都处理完之后,结束;
Sed的常用操作选项
- sed常用选项
选项 | 含义 |
---|---|
-e | 进行多次编辑 |
-n | 取消默认输出 |
-f | 指定sed文件名 |
-i | 直接在源文件中修改 |
-r | 使用扩展正则表达式 |
- sed常用命令动作
以下所有的动作都要在单引号里
命令动作 | 含义 |
---|---|
p | 打印输出 |
d | 删除指定行 |
i | 在指定行之前插入内容 |
a | 在指定行后面插入内容 |
c | 替换指定行所有内容 |
s | 搜索替换 |
举例说明
- 文件准备
# vim a.txt
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
298374837483
172.16.0.254
10.1.1.1
对文件进行增、删、改、查操作
语法:sed 选项 **'\**定位+命令\**'** 需要处理的文件
- 打印文件内容:
[root@server ~]# sed '' a.txt 对文件什么都不做
[root@server ~]# sed -n 'p' a.txt 打印每一行,并取消默认输出
[root@server ~]# sed -n '1p' a.txt 打印第1行
[root@server ~]# sed -n '2p' a.txt 打印第2行
[root@server ~]# sed -n '1,5p' a.txt 打印1到5行
[root@server ~]# sed -n '$p' a.txt 打印最后1行
- 增加文件内容
i 地址定位的上面插入
a 下面插入
[root@server ~]# sed '$a99999' a.txt 文件最后一行下面增加内容
[root@server ~]# sed 'a99999' a.txt 文件每行下面增加内容
[root@server ~]# sed '5a99999' a.txt 文件第5行下面增加内容
[root@server ~]# sed '$i99999' a.txt 文件最后一行上一行增加内容
[root@server ~]# sed 'i99999' a.txt 文件每行上一行增加内容
[root@server ~]# sed '6i99999' a.txt 文件第6行上一行增加内容
[root@server ~]# sed '/^uucp/ihello' 以uucp开头行的上一行插入内容
- 修改文件内容
c 替换指定的整行内容
[root@server ~]# sed '5chello world' a.txt 替换文件第5行内容
[root@server ~]# sed 'chello world' a.txt 替换文件所有内容
[root@server ~]# sed '1,5chello world' a.txt 替换文件1到5号内容为hello world
[root@server ~]# sed '/^user01/c888888' a.txt 替换以user01开头的行
- 删除文件内容
[root@server ~]# sed '1d' a.txt 删除文件第1行
[root@server ~]# sed '1,5d' a.txt 删除文件1到5行
[root@server ~]# sed '$d' a.txt 删除文件最后一行
对文件进行搜索替换操作
语法:sed 选项 's/搜索的内容/替换的内容/动作' 需要处理的文件
其中,s表示search搜索;斜杠/表示分隔符,可以自己定义;动作一般是打印p和全局替换g
[root@server ~]# sed -n 's/root/ROOT/p' 1.txt
[root@server ~]# sed -n 's/root/ROOT/gp' 1.txt
[root@server ~]# sed -n 's/^#//gp' 1.txt
[root@server ~]# sed -n 's@/sbin/nologin@itcast@gp' a.txt
[root@server ~]# sed -n 's/\/sbin\/nologin/itcast/gp' a.txt
[root@server ~]# sed -n '10s#/sbin/nologin#itcast#p' a.txt
uucp:x:10:14:uucp:/var/spool/uucp:itcast
[root@server ~]# sed -n 's@/sbin/nologin@itcastheima@p' 2.txt
注意:搜索替换中的分隔符可以自己指定
[root@server ~]# sed -n '1,5s/^/#/p' a.txt 注释掉文件的1-5行内容
#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
其他命令
H:复制到剪切板
g、G:将剪切板的数据覆盖/追加到指定行
w:保存为文件
r:读取指定文件
a:追加指定文件
[root@server ~]# sed '3r /etc/hosts' passwd.txt //将/etc/hosts文件插入到第三行后面
[root@server ~]# sed -n '1,5w 22.txt' passwd.txt //把1-5行内容写入到22.txt文件
[root@server ~]# sed = passwd.txt//显示行号
修改源文件的本质其实就是将-n换成-i,-i不要和‘p’同时使用,-n和-i也不要一起使用
Sed写入脚本
sed写入脚本 ,脚本上面就不是#!/bin/bash ,而是 #/bin/sed -f
写入脚本的代码也不需要在前面加sed -n 之类的 直接写入后面单引号里的代码
如何运行sed 脚本
sed -f sed.sh xx.txt
sed -i -f sed.sh xx.txt 对文件操作并修改源文件
Awk工具介绍
- awk是一种编程语言,主要用于在linux/unix下对文本和数据进行处理,是linux/unix下的一个工具。数据可以来自标准输入、一个或多个文件,或其它命令的输出。
- awk的处理文本和数据的方式:逐行扫描文件,默认从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。
- awk分别代表其作者姓氏的第一个字母。因为它的作者是三个人,分别是Alfred Aho、Brian Kernighan、Peter Weinberger。
- gawk是awk的GNU版本,它提供了Bell实验室和GNU的一些扩展。
Awk能做什么
- awk用来处理文件和数据的,是类unix下的一个工具,也是一种编程语言
- 可以用来统计数据,比如网站的访问量,访问的IP量等等
- 支持条件判断,支持for和while循环
工作原理:
- 当读到第一行时,匹配条件,然后执行指定动作,再接着读取第二行数据处理,不会默认输出
- 如果没有定义匹配条件默认是匹配所有数据行,awk隐含循环,条件匹配多少次动作就会执行多少次
命令行模式使用
- 命令格式:
awk 选项 '模式或条件{操作}' 文件1文件2...
awk -f 脚本文件 文件1 文件2...
awk常见的内建变量(可直接用):
FS:列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用 相同
NF:当前处理的行的字段个数。
NR:当前处理的行的行号(序数)。
$O: 当前处理的行的整行内容。
$n:当前处理行的第n个字段(第n列)。
FILENAME:被处理的文件名。
RS:行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk-次仅读入一 条记录,以进行处理。预设值是'\n'
按行输出文本
awk ' {print}' testfile2 //输出所有内容
awk ' {print $0}' testfile2 //输出所有内容
awk 'NR==1, NR==3{print}' testfile2 //输出第1~3行内容
awk ' (NR>=1) && (NR<=3) {print}' testfile2 //输出第1~3行内容
awk 'NR==11 | NR==3{print}' testfile2 //输出第1行、第3行内容
awk ' (NR%2)=1{print}' testfile2 //输出所有奇数行的内容
awk ' (NR%2)==0{print}' testfile2 //输出所有偶数行的内容
awk '/^root/ {print}' /etc/passwd //输出以root 开头的行
awk ' /nologin$/ {print}' /etc/passwd //输出以nologin 结尾的行
awk 'BEGIN {x=0};/\/bin\/bash$/{x++};END {print x}' /etc/passwd
//统计以/bin/bash结尾的行数,等同于grep -c"/bin/bash$" /etc/passwd
按字段输入文本
awk -F ":" ' {print $3}' /etc/passwd //输出每行中(以空格或制表位分隔)的第3个字段
awk -E ":" {print $1,$3}' /etc/passwd //输出每行中的第1、3个字段
awk -F ":" '$3<5{print $1,$3}' /etc/passwd //输出第3个字段的值小于5的第1、3个字段内容
awk -F ":" '! ($3<200) {print}' /etc/ passwd //输出第3个字段的值不小于200的行
awk 'BEGIN {FS=":"}; {if($3>=200) {print}}' /etc/passwd //先处理完BEGIN的内容,再打印文本里面的内容
awk -F ":" ' {max= ($3>$4) ?$3:$4; {print max}}' /etc/passwd
//($3>$4)?$3:$4三元运算符, 如果第3个字段的值大于第4个字段的值,则把第3个字段的值赋给max, 否则第4个字段的值赋
awk -F ":" '{print NR,$0}' /etc/passwd //输出每行内容和行号,每处理完一条 记录,NR值加1
awk -F ":"'$7~"/bash"{print $1}' /etc/passwd //输出以冒号分隔且第7个字段中包含/bash的行的第1个字段
awk -F ":" ' ($1~"root")&& (NF==7) {print $1,$2}' /etc/passwd //输出第1个字段中包含root且有7个字段的行的第1、2个字段
通过管道符,双引号调用Shell命令
echo $PATH | awk ' BEGIN{RS=":"} ; END{print NR} '
//统计以冒号分隔的文本段落数,END{}语句块中,往往会放入打印结果等语句
awk -F: ' /bash$/{print | "wc -l"}' /etc/passwd
//调用wc -1命令统计使用bash的用户个数,等同于grep -c "bash$" /etc/passwd
free -m 1 awk ' /Mem:/ {print int ($3/ ($3+$4)*100)"%"}'
//查看当前内存使用百分比
top -b -n 1 | grep Cpu | awk -F ',' '{print $4}' | awk '{print $1}'
//查看当前CPU空闲率,(-b -n 1表示只需要1次的输出结果)
date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H: %M: %S"
//显示上次系统重启时间,等同于uptime; second ago为显示多少秒前的时间,+"%F %H: %M:%S"等同于+"%Y-%m-%d%H:%M:%S"的时间格式:
awk 'BEGIN {n=0 ; while ("w" | getline) n++ ; {print n-2}}'
//调用w命令,并用来统计在线用户数
awk 'BEGIN {n=0 ; while ("w" | getline) n++ ; {print n-2}}'
//调用w命令,并用来统计在线用户数