Linux文本处理

# linux文本处理

正则表达式

正则表达式是为例处理大量的文本/字符串而定义的一套规则和方法。Linux正则表达式一般以行为单位处理

正则表达式是一种用于匹配和操作文本的强大工具,它是由一系列字符和特殊字符组成的模式,用于描述要匹配的文本模式。

通配符 vs 正则表达式

正则表达式用来找:【文件】内容、文本、字符串,一般只有grep、sed和awk支持。

通配符用来找:文件名,普通命令都支持

正则表达式分类:

  • 基本正则表达式(BER)

    只承认的元字符有**^$.[]***,其它字符被识别为普通字符。

  • 扩展正则表达式(ERE)

    在BER的元字符基础上加上了()、{}、?、+、|等

只有在用反斜杠\进行转义的情况下,字符(){}才会在BER被当作元字符处理,而ERE中,任何原符号前面加上反斜杠反而会使其被当作普通字符来处理。

基础正则表达式

在学习正则表达式的时候,有些地方可能读起来不那么容易理解,而且这么多表达式很容易忘记,大家可以到一个叫编程胶囊的网页去练习,容易理解而且动手操作印象会更深一点。
编程胶囊

^
^word:搜索以word开头的内容
$
word$:搜索以word结尾的内容
^$:表示空行
.代表且只能代表任意一个字符(不匹配空行),只能出现在方括号以外
\转义字符
*重复之前的字符或文本0个或多个,之前的文本或字符连续0次或多次,等价于{0,}
.*任意多个字符
^.*以任意多个字符串开头,.*尽可能多,有多少算多少
括号表达式[]:匹配字符集合内任意一个字符:[a-z]匹配所有小写字母。
[^abc]匹配不含^后的任意字符a或b或c,是对[abc]的取反
[:alnum:]字母和数字
[:alpha:]代表任何英文大小写字符
[:lower:]小写字母
[:upper:]大写字母
[:space:]包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白
a\{n,m\}重复a字符n到m次。
a\{n,\}重复前面a字符至少n次
\w 可以与任意单词字符匹配。
d即digit数字的意思,等价于[0-9]
\s匹配空白字符

扩展正则表达式ERE

{N}在它之前的字符组中出现N次
+ 重复前一个字符一次或一次以上,前一个字符连续一个或多个,把连续的文本字符取出,等价于{1,}
? 重复前面一个字符0次或1次,等价于{0,1}
|管道符:表示同时过滤多个字符,即or条件
()对数据进行分组,除了获取整个匹配外,还能再匹配中选择每一个分组
有时候,我们并不需要捕获某个分组的内容,但是又想使用分组的特性.这个时候就可以使用非捕获组(?:表达式),从而不捕获数据,还能使用分组的功能。
使用\N可以引用编号为N的分组
正则practice
# 匹配所有的数字、大写字母和小写字母
[0-9a-zA-Z]
# 匹配[]、------、--、()特殊字符
[\[\]\-\(\)]
# 匹配含有数字或字母的单词
[\w\d]
# 匹配爱后面不包含你的数据
爱[^你]
# 匹配不包含小写字母的数据
[^a-z]
# 匹配空白分割的单词 \s
# 单词边界 \b
# 匹配不以字母开头的单词
^\W
# 匹配以OS结尾的字符串
OS$
# 匹配任意字母之后是ar的字符串
.ar
# 使用正则来匹配 favorite和favourite这两种写法
favou?rite  # u?表示u是可选的
# 匹配以f开头的数据
^f.
# 匹配手机号码,第一位数字必须是1,第二位数字必须是[3,4,5,7,8]中的一个,后面9个树是[0-9]中的任意一个数字
1[3-67-8][0-9]{9}
# 匹配以http开头,以/结尾的所有数据
^http.*/$或^http.+/$
# 使用分组提取<p></p>中的数据
(<p>)(.*)(</p>)
# 匹配符合ab ba这种关系的单词
(\w)(\w).*(\2)(\1)



在这里插入图片描述

文本处理三剑客:grep、sed、awk。

grep:对文本内容进行过滤、筛选

sed:对文件或数据流进行加工处理

grep

Global search Regular Expression and Print out the line

利用”正则表达式”进行”全局搜索”的工具

  • grep:支持正则表达式
  • egrep:支持扩展正则表达式,相当于grep -E
  • fgrep:不支持正则表达式,只匹配写死的字符串,但是速度很快

文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印到匹配的行。

grep [OPTIONS] PATTERN [FILE...]

–color=auto 对匹配到的文本着色显示
-m # 匹配#次后停止
-v 显示不被pattern匹配到的行
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-q 静默模式,不输出任何信息
-A # after, 后#行
-B # before, 前#行
-C # context, 前后各#行
-e 实现多个选项间的逻辑or关系,如:grep –e ‘cat ’ -e ‘dog’ file
-w 匹配整个单词
-E 使用ERE,相当于egrep
-F 不支持正则表达式,相当于fgrep
-f file 根据模式文件处理
-r 递归目录,但不处理软链接
-R 递归目录,但处理软链接
# 查找grep中含有test字符串的行
[liusongle@localhost Desktop]$ grep "test" greptest
lsl test
this is a grep test
test
# 不区分大小写,查找含有字符串t/T e/E s/S t/T的行      -i
[liusongle@localhost Desktop]$ grep -i "test" greptest
lsl test
this is a grep test
test
Test
# 不区分大小写,查找含有字符串test的行并显示行号       -n
[liusongle@localhost Desktop]$ grep -i -n "test" greptest
1:lsl test
2:this is a grep test
5:test
9:Test
# 高亮显示查找字符串test(CentOS7中自带此功能)
[liusongle@localhost Desktop]$ grep -i --color "test" greptest
lsl test
this is a grep test
test
Test
# 只查找指定字符串
[liusongle@localhost Desktop]$ grep -i -o "test" greptest
test
test
test
Test
# 查找userinfo中年龄为22的人的姓名  -Bn:显示搜索结果及其之前n行
[liusongle@localhost Desktop]$ grep -B1 "age:22" userinfo 
name:liusongle
age:22
--
name:liusongyi
age:22
# -An 显示搜索结果及其之后n行
# -Cn 显示搜索结果及前后各n行
[liusongle@localhost Desktop]$ grep -C1 "age:22" userinfo
name:liusongle
age:22
sex:female
--
name:liusongyi
age:22
sex:female
[liusongle@localhost Desktop]$ 
# 精确匹配字符串 查找出名字为liusong的用户信息  -w
[liusongle@localhost Desktop]$ grep -A2 -w "liusongle" userinfo
name:liusongle
age:22
sex:female
# 查找不含字符串liusong的行
[liusongle@localhost Desktop]$ grep -n -v "liusong" userinfo
2:age:22
3:sex:female
4:
5:name:zhangsanfeng
6:age:80
7:sex:male
8:
10:age:22
11:sex:female
12: 
14:age:18
15:sex:female
# 查看userinfo中含有liusongle或“liusongyi”的行   -e
[liusongle@localhost Desktop]$ grep -e "liusongle" -e "liusongyi" userinfo
name:liusongle
name:liusongyi
# 是否有字符串匹配到sex
# 静默模式下grep不会输入任何信息,无论是否匹配到指定的字符串,都不会输出任何信息,所以,我们需要配合”echo $?”命令,查看命令的执行状态,如果返回值为0,证明上一条grep命令匹配到了指定的字符串,如果返回值为1,则证明上一条grep命令没有匹配到指定的字符串
[liusongle@localhost Desktop]$ grep -q "liusong" userinfo
[liusongle@localhost Desktop]$ echo $?
0
[liusongle@localhost Desktop]$ grep -q "ceshi" userinfo
[liusongle@localhost Desktop]$ echo $?
1
[liusongle@localhost Desktop]$ 

sed

Stream Editor:文本流编辑器,sed是一个“非交互式的”面向字符流的编辑器。能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上。还可以对原文件改动,但是不会在屏幕上返回结果。

sed的工作原理

sed命令面向“行”进行处理,每一次处理一行内容。处理时,sed会把要处理的行存储在缓冲区中(sed模式空间),接着用 sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。符合模式的处理后输出,不符合模式的按原样输出。这个缓冲区被称为“模式空间”(pattern space)。“在这个处理过程中,sed 命令并不会对文件本身进行任何更改。”

sed 【选项】【sed内置命令字符】【输入文件】

选项
-n:取消默认输出,只对匹配上规则并进行过处理的行进行输出
-i:直接将修改结果写入文件(修改原文件内容)
-e:多次编辑,不需要管道符(可以设置多个匹配规则)
-r:支持正则扩展(默认只支持基本正则表达式)
-f:设定sed 命令的command部分

内置命令字符(用于实现对文本的增删改查)
a:append,对文本追加,在指定行后面添加一行/多行数据
d:delete,匹配删除行
i:insert,表示插入文本,在指定行前面添加一行/多行数据
p:print,打印匹配行的内容,通常p和-n一起用
s/正则/替换内容/g:匹配正则内容,然后替换内容(支持正则),结果g代表全局匹配。

sed匹配范围
空地址:全文处理
单地址:指定文件的某一行
/pattern/:被模式匹配到的每一行
范围区间:10,20(10到20行),10,+5(第10行向下5行)/pattern1/,/pattern2/
步长:1~2表示1、3、5、7、9行,2~2两个步长表示2、4、6、8、10、偶数行
# 1.输出文件的第2,3行
[liusongle@localhost ~]$ sed -n "2,3p" luffycity.txt
I learn linux.
I like play baseketball.
# 2.从第2行开始连续输出三行
[liusongle@localhost ~]$ sed -n "2,+3p" luffycity.txt
I learn linux.
I like play baseketball.
My QQ is 30689496960
My mother is liuyanqiong.
# 3.输出带有linux的行
[liusongle@localhost ~]$ sed -n "/linux/p" luffycity.txt
I learn linux.
# 4.将带有mother的行从原文件中删除
[liusongle@localhost ~]$ sed "/mother/d" luffycity.txt
My name is chaoge.
I learn linux.
I like play baseketball.
My QQ is 30689496960
[liusongle@localhost ~]$ cat luffycity.txt
My name is chaoge.
I learn linux.
I like play baseketball.
My QQ is 30689496960
My mother is liuyanqiong.
# 加了-i才会在原为文件中进行操作
[liusongle@localhost ~]$ sed  -i "/mother/d" luffycity.txt
[liusongle@localhost ~]$ cat luffycity.txt
My name is chaoge.
I learn linux.
I like play baseketball.
My QQ is 30689496960
# 5.删除第五行到结尾
[liusongle@localhost ~]$ sed '5,$d' luffycity.txt
My name is chaoge.
I learn linux.
I like play baseketball.
My QQ is 30689496960.
# 6.将文件中的MY全部替换为Her,同时替换掉QQ号为88888888
[liusongle@localhost ~]$ sed -e "s/My/Her/g" -e "s/30689496960/88888888/g" luffycity.txt 
Her name is chaoge.
I learn linux.
I like play baseketball.
Her QQ is 88888888.
this is a test.
this is a test.
this is a test.
this is a test.
# 7.在文件第二行追加内容,写入到文件
[liusongle@localhost ~]$ cat luffycity.txt
My name is chaoge.
I learn linux.
My linux is good
I like play baseketball.
My QQ is 30689496960.
this is a test.
this is a test.
this is a test.
this is a test.
# 8.在文件第4行前面插入内容,写入到文件
[liusongle@localhost ~]$ sed -i "4i My telephone is 1233546789765" luffycity.txt
[liusongle@localhost ~]$ cat luffycity.txt
My name is chaoge.
I learn linux.
My linux is good
My telephone is 1233546789765
I like play baseketball.
My QQ is 30689496960.
this is a test.
this is a test.
this is a test.
this is a test.
# 9.在第三行下面加入两行数据,写入到文件
[liusongle@localhost ~]$ sed -i "3a I like girl.\nI like pretty girl." luffycity.txt
[liusongle@localhost ~]$ cat luffycity.txt
My name is chaoge.
I learn linux.
My linux is good
I like girl.
I like pretty girl.
My telephone is 1233546789765
I like play baseketball.
My QQ is 30689496960.
this is a test.
this is a test.
this is a test.
this is a test.
# 10.在每一行下面添加“---------”
[liusongle@localhost ~]$ sed -i "a ---------" luffycity.txt
[liusongle@localhost ~]$ cat -n luffycity.txt
     1	My name is chaoge.
     2	---------
     3	I learn linux.
     4	---------
     5	My linux is good
     6	---------
     7	I like girl.
     8	---------
     9	I like pretty girl.
    10	---------
    11	My telephone is 1233546789765
    12	---------
    13	I like play baseketball.
    14	---------
    15	My QQ is 30689496960.
    16	---------

取出linux的IP地址
[liusongle@localhost ~]$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.238.129  netmask 255.255.255.0  broadcast 192.168.238.255
        inet6 fe80::91e4:db45:d2af:c9cd  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:10:ad:fd  txqueuelen 1000  (Ethernet)
        RX packets 113  bytes 20555 (20.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 130  bytes 14130 (13.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 68  bytes 5920 (5.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 68  bytes 5920 (5.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

virbr0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        ether 52:54:00:d7:f0:e8  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  1. ifconfig的输出通过管道传给sed,sed查找出第二行的内容

    [liusongle@localhost ~]$ ifconfig ens33 | sed -n "2p"
            inet 192.168.238.129  netmask 255.255.255.0  broadcast 192.168.238.255
    
  2. 去掉IP地址之前的内容(将IP地址之前的内容替换为空)

    [liusongle@localhost ~]$ ifconfig ens33 | sed -n "2p" | sed  "s/^.*inet//"
     192.168.238.129  netmask 255.255.255.0  broadcast 192.168.238.255
    
  3. 去掉IP地址之后的内容

    [liusongle@localhost ~]$ ifconfig ens33 | sed -n "2p" | sed  "s/^.*inet//" | sed "s/net.*$//"
     192.168.238.129  
    [liusongle@localhost ~]$ 
    

或者,利用-e参数进行多次编辑

[liusongle@localhost ~]$ ifconfig ens33 |sed -e "2s/^.*inet//" -e "2s/net.*$//p" -n
 192.168.238.129  

awk

逐行读取文本,默认以空格或tab键为分隔符进行分割,将分割所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。

awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。在使用awk命令的过程中,可以使用逻辑操作符“&&”表示“与”、“||”表示“或”、“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余和乘方。

awk 选项 ‘模式或条件{操作}’ 文件1 文件2
awk -f 脚本文件 文件1 文件2

awk常见的内建变量:

FS:列分隔符。指定每行文本的字段分隔符,默认为空格或制表位。
NF:当前处理的行的字段个数
NR:当前处理的行的行号
$0:当前处理的行的整行内容
$n:当前处理的行的第n个字段
FILENAME:被处理的文件名
RS:行分割符。awk从文件上读取资料时,将根据RS的定义把读取的资料切割成许多条记录,而awk一次仅读入一条记录,以进行处理。预设值是’\n’。
#1.按行输出文本,输出所有内容
awk '{print $0}' luffycity.txt
awk '{print}' luffycity.txt
#2.输出1~3行的内容
awk 'NR==1,NR==3{print}' luffycity.txt
awk '(NR>=1)&&(NR<=3){print}' luffycity.txt
#3.输出第1行和第3行的内容
awk 'NR==1;NR==3{print}' luffycity.txt
awk 'NR==1||NR==3{print}' luffycity.txt
#4.输出所有奇数/偶数行的内容
awk '(NR%2==1){print}' luffycity.txt
awk '(NR%2==0){print}' luffycity.txt
#5.输出以My开头的行
awk '/^My/{print}' luffycity.txt
#6.输出以good结尾的行
awk '/good$/{print}' luffycity.txt
#7.统计/etc/passwd文件中以/bin/bash结尾的行
#注意:BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作;awk再处理指定的文本,之后再执行END模式中指定的动作,END{}语句块中,往往会放入打印结果等语句
awk 'BEGIN {X=0}; /\/bin\/bash$/{x++}; END{print x}' /etc/passwd
#8.输出每行(以:分割)中的第1个字段
awk -F ":" '{print $1}' /etc/passwd
#9.输出每行(以:分割)中的第1、2、3个字段
awk -F ":" '{print $1,$2,$3}' /etc/passwd
#10.输出第3个字段的值不小于5的行的第1、3个字段的内容
awk -F ":" '$3<5{print $3,$5}' /etc/passwd
#11.输出第3个字段的值不小于200的行
awk -F ":" '!($3<200){print}' /etc/passwd

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值