shell 5

基本正则

^ 开始
$ 结尾
[ ] 集合
[ ^ ] 对集和取反
. 任意单个字符
* 匹配前一个字符出现了任意次包括0【*不能单独使用】
\{n,m\} 匹配前一个字符出现了n到m次
\{n,\} 匹配前一个字符出现了n次以上
\{n\} 匹配前一个字符出现了出现了n次
----------------------------------------
扩展正则

+ 至少1次 a+
? 0次或1次 a?
{n,m} n次到m次
() (ab){n,m} 组合为整体,保留
| 或者
\b 单词边界

基本正则: 兼容性强,几乎所有软件都支持,书写麻烦
扩展正则: 相反(兼容性差,书写简单),像grep就不支持扩展正则,但是egrep支持扩展正则
egrep "test | teast" 1.txt
---------------------------------------------
\b 单词边界

# grep the a.txt
the hlsidkg
kaldf kdlgtheeelsk klsls
adfg sifthe lskd
thekxikk wkigos

# egrep "\bthe\b" a.txt
the hlsidkg

# egrep "\bthe" a.txt
the hlsidkg
thekxikk wkigos

# egrep "the\b" a.txt
the hlsidkg
adfg sifthe lskd
-------------------------------------------
sed 流式编辑器
非交互
逐行处理
具备和vim一样的功能

vim
:r 导入
:w 导出
-----------------------------------------
用法1:前置命令 | sed [选项] '条件指令'
用法2:sed [选项] '条件指令' 文件.. ..

sed命令的常用选项如下:
-n(屏蔽默认输出,默认sed会输出读取文档的全部内容)
-r(让sed支持扩展正则)
-i(sed直接修改源文件,默认sed只是通过内存临时修改文件,源文件无影响)

1)sed命令的 -n 选项
执行p打印等过滤操作时,希望看到的是符合条件的文本。但不使用任何选项时,默认会将原始文本一并输出,从而干扰过滤效果。比如,尝试用sed输出/etc/hosts的第1行:
--------------------------------------------
-n(屏蔽默认输出,默认sed会输出读取文档的全部内容)

# sed '1p' /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

172.25.254.254 classroom.example.com
172.25.254.254 content.example.com

# sed -n '1p' /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
-------------------------------------------
CPU--内存--硬盘(a.txt)

-i(sed直接修改源文件,默认sed只是通过内存临时修改文件,源文件无影响)

编辑重要文件的时候,命令行不要加-i。
确认没问题了,添加到脚本里时再加-i。因为-i是直接修改源文件!!!无法不保存退出的。

# cat a.txt
the hlsidkg
kaldf kdlgtheeelsk klsls
adfg sifthe lskd
thekxikk wkigos

# sed 'd' a.txt #源文件没有变
# wc -l a.txt
4 a.txt

# sed -i 'd' a.txt #直接修改源文件
# ll a.txt
-rw-r--r--. 1 root root 0 10月 26 10:27 a.txt
# wc -l a.txt
0 a.txt
----------------------------------------
-n(屏蔽默认输出,默认sed会输出读取文档的全部内容)
p是显示第几行

# sed -n '3,6p' /etc/passwd #显示3-6行
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
---------------------------------------
vim 1.txt
11111111111111111111111111
2222222222222222222222222222
33333333333333333333333333
4444444444444444444444444444444
55555555555555555555555555555555
66666666666666666666666666666666666
7777777777777777777777777777777777777777
88888888888888888888888888888888888888888
99999999999999999999999999999999999999999999
0000000000000000000000000000000000000000
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ddddddddddddddddddddddddddddddddddddd
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
jjjjjjjjjjjjjjjjjjjjjjjjjjjjj
kkkkkkkkkkkkkkkkkkkkkkkkkkkkk
llllllllllllllllllllllllllllllllllllll
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
rrrrrrrrrrrrrrrrrrrrr
eeeeeeeeeeeeeeeeeeeeeeeeeeee
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
------------------------------------------------------
# sed -n '1p;3p;8p' 1.txt #第1行,第3行,第8行。用;分隔
11111111111111111111111111
33333333333333333333333333
88888888888888888888888888888888888888888
-------------------------------------------------------------------
# sed -i '3,6d' 1.txt
[root@server0 ~]# cat 1.txt
11111111111111111111111111
2222222222222222222222222222
7777777777777777777777777777777777777777
88888888888888888888888888888888888888888
99999999999999999999999999999999999999999999
0000000000000000000000000000000000000000
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ddddddddddddddddddddddddddddddddddddd
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
jjjjjjjjjjjjjjjjjjjjjjjjjjjjj
kkkkkkkkkkkkkkkkkkkkkkkkkkkkk
llllllllllllllllllllllllllllllllllllll
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
rrrrrrrrrrrrrrrrrrrrr
eeeeeeeeeeeeeeeeeeeeeeeeeeee
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
------------------------------------------------------
sed [选项] '条件指令' 文件.. ..
sed命令可以使用行号或正则做为条件匹配:
1)行号案例
打印第3行:
[root@svr5 ~]# sed -n '3p' /etc/passwd

打印第3到5行:
[root@svr5 ~]# sed -n '3,5p' /etc/passwd

打印第3和5行:
[root@svr5 ~]# sed -n '3p;5p' /etc/passwd

打印第3以及后面的10行:
[root@svr5 ~]# sed -n '3,+10p' /etc/passwd
--------------------------------------------------------
# sed -n '3,+10p' 1.txt
33333333333333333333333333
4444444444444444444444444444444
55555555555555555555555555555555
66666666666666666666666666666666666
7777777777777777777777777777777777777777
88888888888888888888888888888888888888888
99999999999999999999999999999999999999999999
0000000000000000000000000000000000000000
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ddddddddddddddddddddddddddddddddddddd
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
---------------------------------------------------------
步长,从第一行开始,每隔2行,显示一次

打印奇数行:
[root@svr5 ~]# sed -n '1~2p' /etc/passwd #从第一行开始,每隔2行,显示一次

打印偶数行:
[root@svr5 ~]# sed -n '2~2p' /etc/passwd
----------------------------------------------------------
]# cat /root/sed1.sh
#!/bin/bash
while :
do
clear
n=`cat user.txt | wc -l`
line=$[RANDOM%n+1]
sed -n "${line}p" user.txt
sleep 0.2
done
------------------------------------------------
# cat /root/user.txt
大一
达二
张三
李四
王五
赵六
七七
八八
小九
---------------------------------------------------
# sed -n '/root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# sed -n '/bash$/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
student:x:1000:1000:Student User:/home/student:/bin/bash
kenji:x:1001:1001::/home/kenji:/bin/bash
chihiro:x:1002:1002::/home/chihiro:/bin/bash
harry:x:1003:1003::/home/harry:/bin/bash

# sed -n '/^root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
--------------------------------------------------
2)正则案例

打印包含root的行:
[root@svr5 ~]# sed -n '/root/p' /etc/passwd

打印bash结尾的行:
[root@svr5 ~]# sed -n '/bash$/p' /etc/passwd

3)没有条件,则表示匹配所有行
[root@svr5 ~]# sed -n 'p' /etc/passwd
--------------------------------------------------
= 表示显示行号

# sed -n '$=' /etc/passwd #这个的效率会更高,因为只用了一个程序.在此$表示整个文件的结尾
70

# wc -l /etc/passwd
70 /etc/passwd
-------------------------------------------
# cat -n /etc/passwd | grep root
1 root:x:0:0:root:/root:/bin/bash
10 operator:x:11:0:operator:/root:/sbin/nologin

# sed -n '/root/=' /etc/passwd #和wc -l的区别是,sed只显示数字。而wc -l还显示文件名
1
10

# wc -l /etc/passwd
70 /etc/passwd
----------------------------------------
sed工具的p指令案例集锦(自己提前生成一个a.txt文件)
[root@svr5 ~]# sed -n 'p' a.txt //输出所有行,等同于cat a.txt
[root@svr5 ~]# sed -n '4p' a.txt //输出第4行
[root@svr5 ~]# sed -n '4,7p' a.txt //输出第4~7行
[root@svr5 ~]# sed -n '4,+10p' a.txt //输出第4行及其后的10行内容
[root@svr5 ~]# sed -n '/^bin/p' a.txt //输出以bin开头的行
[root@svr5 ~]# sed -n '$=' a.txt //输出文件的行数,在此$表示整个文件的结尾
--------------------------------------------------
sed工具的d指令案例集锦(自己提前生成一个a.txt文件)
[root@svr5 ~]# sed '3,5d' a.txt //删除第3~5行
[root@svr5 ~]# sed '/xml/d' a.txt //删除所有包含xml的行
[root@svr5 ~]# sed '/xml/!d' a.txt //删除不包含xml的行,!符号表示取反
[root@svr5 ~]# sed '/^install/d' a.txt //删除以install开头的行
[root@svr5 ~]# sed '$d' a.txt //删除文件的最后一行
[root@svr5 ~]# sed '/^$/d' a.txt //删除所有空行,读一行,执行一遍,相当于for循环
--------------------------------------------------
# cat 2.txt
2017 2018 2019
2017 2017 2018
2017 2017 2017

# sed 's/2017/3303/' 2.txt #替换行的第一位数,逐行去读,符合就改。和vim不一样的是,它替换光标当前的那一行
3303 2018 2019
3303 2017 2018
3303 2017 2017

# sed 's/2017/xxxx/g' 2.txt #替换所有
xxxx 2018 2019
xxxx xxxx 2018
xxxx xxxx xxxx

# sed '1s/2017/0000/g' 2.txt #替换第一行的所有
0000 2018 2019
2017 2017 2018
2017 2017 2017

# sed '2s/2017/0000/g' 2.txt #替换第二行的所有
2017 2018 2019
0000 0000 2018
2017 2017 2017

# sed '2s/2017/0000/' 2.txt #后面不加g,默认只替换第一个
2017 2018 2019
0000 2017 2018
2017 2017 2017

# sed '3s/2017/0000/2' 2.txt #替换第三行的第2个
2017 2018 2019
2017 2017 2018
2017 0000 2017

# sed '3s/2017//2' 2.txt #不写替换成谁,直接就是空
2017 2018 2019
2017 2017 2018
2017 2017
-------------------------------------------------
sed命令的s替换基本功能(s/旧内容/新内容/选项):
[root@svr5 ~]# vim test.txt //新建素材
2017 2011 2018
2017 2017 2024
2017 2017 2017
[root@svr5 ~]# sed 's/2017/xxxx/' test.txt
[root@svr5 ~]# sed 's/2017/xxxx/g' test.txt
[root@svr5 ~]# sed 's/2017/xxxx/2' test.txt
[root@svr5 ~]# sed 's/2017//2' test.txt
[root@svr5 ~]# sed -n 's/2017/xxxx/p' test.txt
-------------------------------------------------
# sed 's/2019/xxxx/' 2.txt
2017 2018 xxxx
2017 2017 2018
2017 2017 2017

# sed -n 's/2019/xxxx/' 2.txt

# sed -n 's/2019/xxxx/p' 2.txt #-n是不显示,p是只显示被替换的
2017 2018 xxxx

# sed -n 's/root/abc/p' /etc/passwd
abc:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/abc:/sbin/nologin
-------------------------------------------------
下面看看sed工具的s指令案例集锦(自己提前生成一个a.txt文件)
注意:替换操作的分隔“/”可改用其他字符,如#、&等,便于修改文件路径

sed '多少行s/旧/新/第几个' 文件

[root@svr5 ~]# sed 's/xml/XML/' a.txt //将每行中第一个xml替换为XML
[root@svr5 ~]# sed 's/xml/XML/3' a.txt //将每行中的第3个xml替换为XML
[root@svr5 ~]# sed 's/xml/XML/g' a.txt //将所有的xml都替换为XML
[root@svr5 ~]# sed 's/xml//g' a.txt //将所有的xml都删除(替换为空串)
[root@svr5 ~]# sed 's#/bin/bash#/sbin/sh#' a.txt //将/bin/bash替换为/sbin/sh
[root@svr5 ~]# sed '4,7s/^/#/' a.txt //将第4~7行注释掉(行首加#号)
[root@svr5 ~]# sed 's/^#an/an/' a.txt //解除以#an开头的行的注释(去除行首的#号)
----------------------------------------------------------
替换操作的分隔“/”可改用其他字符,如#、&等,便于修改文件路径

# sed -n 's#bin/bash#sbin/sh#p' /etc/passwd
root:x:0:0:root:/root:/sbin/sh
student:x:1000:1000:Student User:/home/student:/sbin/sh
kenji:x:1001:1001::/home/kenji:/sbin/sh
chihiro:x:1002:1002::/home/chihiro:/sbin/sh
harry:x:1003:1003::/home/harry:/sbin/sh

# sed -n 's&bin/bash&sbin/sh&p' /etc/passwd
root:x:0:0:root:/root:/sbin/sh
student:x:1000:1000:Student User:/home/student:/sbin/sh
kenji:x:1001:1001::/home/kenji:/sbin/sh
chihiro:x:1002:1002::/home/chihiro:/sbin/sh
harry:x:1003:1003::/home/harry:/sbin/sh
---------------------------------------------------
格式: sed 's/旧/新/第几个字符' 文本文件

# sed 's/.//4' a.txt # s是替换,一个.代表任意单个字符,不写代表空,就是删除。4代表当前行的第4个字符。

# cat 3.txt
hello
ni hao beijing
wo shi shei
yes
good

# sed 's/.//2' 3.txt #把第2个的任意一个字符删掉,逐行处理,每行都删掉
hllo
n hao beijing
w shi shei
ys
god

# sed 's/.$//' 3.txt #把最后一个字符删掉,逐行处理,每行都删掉
hell
ni hao beijin
wo shi she
ye
goo
-------------------------------------------------
() 保留

(abc)(ttt)(123)
\3\1\2 这个表示第3个括号,第1个括号,第2个括号

# cat 3.txt
hello
ni hao beijing
wo shi shei
yes
good

# sed -r 's/(beijing)/ni hao \1/' 3.txt #把beijing替换成ni hao beijing
hello
ni hao ni hao beijing
wo shi shei
yes
good
--------------------------------------------------
? 匹配前面内容0或1次
+ 匹配前面内容至少1次
() 是复制
\1 是粘贴

# cat 4.txt
889009
788898
448555
338755
947586

[root@server0 ~]# sed 's/^/010-/' 4.txt
010-889009
010-788898
010-448555
010-338755
010-947586

# sed 's/([0-9]+)/010\1/' 4.txt
sed:-e 表达式 #1,字符 17:“s”命令的RHS非法引用\1

# sed -r 's/([0-9]+)/010\1/' 4.txt #扩展正则必须加 -r才支持
tom 010889009
abc 010788898
joy 010448555
jim 010338755
amy 010947586

# sed -r 's/([0-9]+)/010-\1/' 4.txt
tom 010-889009
abc 010-788898
joy 010-448555
jim 010-338755
amy 010-947586

# sed -r 's/([0-9]+)/010-\1\1/' 4.txt #可以粘贴多次
tom 010-889009889009
abc 010-788898788898
joy 010-448555448555
jim 010-338755338755
amy 010-947586947586
------------------------------------------------------
# cat 6.txt
hello the world
ni hao beijing
good

# sed -r 's/( )+//' 6.txt
hello the world
ni hao beijing
good
-------------------------------------------------------
利用sed完成本例要求的任务

参考数据文件内容如下:
[root@svr5 ~]# cat nssw.txt
Hello the world
ni hao ma beijing

本小节的操作使用nssw.txt作为测试文件。
1)删除文件中每行的第二个、最后一个字符
分两次替换操作,第一次替换掉第2个字符,第二次替换掉最后一个字符:
[root@svr5 ~]# sed 's/.//2 ; s/.$//' nssw.txt

2)将文件中每行的第一个、倒数第1个字符互换
每行文本拆分为“第1个字符”、“中间的所有字符”、“倒数第1个字符”三个部分,然后通过替换操作重排顺序为“3-2-1”:
[root@svr5 ~]# sed -r 's/^(.)(.*)(.)$/\3\2\1/' nssw.txt

3)删除文件中所有的数字
因原文件内没有数字,行首也没有空格,这里稍作做一点处理,生成一个新测试文件:
[root@svr5 ~]# sed 's/[0-9]//' nssw.txt
以nssw2.txt文件为例,删除所有数字、行首空格的操作如下:
[root@svr5 ~]# sed -r 's/[0-9]//g;s/^( )+//' nssw2.txt

4)为文件中每个大写字母添加括号
使用“()”可实现保留功能,所以可参考下列操作解决:
[root@svr5 ~]# sed -r 's/([A-Z])/[\1]/g' nssw.txt
---------------------------------------------------
# cat 7.txt
Hello The World
Ni Hao Beijing
Good

# sed -r 's#([A-Z])#[\1]#g' 7.txt #把所有的大写字母都加上[ ]
[H]ello [T]he [W]orld
[N]i [H]ao [B]eijing
[G]ood

# sed -r 's#([A-Z])#[\1]#2' 7.txt #只替换第二个
Hello [T]he World
Ni [H]ao Beijing
Good
--------------------------------------------------
sed命令的常用选项如下:
-n(屏蔽默认输出,默认sed会输出读取文档的全部内容)
-r(让sed支持扩展正则)
-i(sed直接修改源文件,默认sed只是通过内存临时修改文件,源文件无影响)

1)sed命令的 -n 选项
执行p打印等过滤操作时,希望看到的是符合条件的文本。但不使用任何选项时,默认会将原始文本一并输出,从而干扰过滤效果。比如,尝试用sed输出/etc/hosts的第1行:


sed
-n屏蔽默认输出
-r让支持扩展正则
-i修改源文件

条件:
行号 1 1,3 1,+3 1~2
/正则/
没有条件,匹配所有
指令:
p查,d删,s改\删
a,i(以行为单位,增),c(行修改)

a是在下一行加入内容
i是在上一行加入内容

而vim中
a是在光标后加入内容
i是在光标前加入内容
----------------------------------------------------
# sed [选项] '条件指令' 文件..
sed工具的多行文本处理操作:

i: 在指定的行之前插入文本
a:在指定的行之后追加文本
c:替换指定的行

# cat 1.txt
Hello The World
Ni Hao Beijing

# sed '1a xxx' 1.txt
Hello The World
xxx
Ni Hao Beijing

# sed '1i xxx' 1.txt
xxx
Hello The World
Ni Hao Beijing

# sed '/Beijing/a xxx' 1.txt #在Beijing后一行加入
Hello The World
Ni Hao Beijing
xxx

# sed '/Beijing/i xxx' 1.txt #在Beijing前一行加入
Hello The World
xxx
Ni Hao Beijing

# sed '2c xxx' 1.txt
Hello The World
xxx

猜你喜欢

转载自www.cnblogs.com/summer2/p/10788026.html