sed命令——Linux三剑客(二)

sed命令

sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

参数说明

参数说明
-i直接修改读取的文件内容,而不是输出到终端
-e以选项中指定的script来处理输入的文本文件
-f以选项中指定的script文件来处理输入的文本文件
-h或–help显示帮助
-n仅显示script处理后的结果
-V或–version 显示版本信息

动作说明

动作说明
a新增,a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
p打印,通常 p 会与参数 sed -n 一起运行
c取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d删除,删除选择的行;
D删除模板块的第一行
i插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
s取代,通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
h拷贝模板块的内容到内存中的缓冲区;
H追加模板块的内容到内存中的缓冲区;
g获得内存缓冲区的内容,并替代当前模板块中的文本;
G获得内存缓冲区的内容,并追加到当前模板块文本的后面;
l列表不能打印字符的清单;
n读取下一个输入行,用下一个命令处理新的行而不是用第一个命令;
N追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码;
p打印模板块的行。 P(大写) 打印模板块的第一行;
q退出Sed;
rfile 从file中读行;
blable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾;
tlabel if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾;
Tlabel 错误分支,从最后一行开始,一旦发生错误或T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾;
wfile 写并追加模板块到file末尾;
Wfile 写并追加模板块的第一行到file末尾;
!表示后面的命令对所有没有被选定的行发生作用;
=打印当前行号;
#把注释扩展到下一个换行符以前;

sed替换标记

标记说明
g表示行内全面替换;
p表示打印行;
w表示把行写入一个文件;
x表示互换模板块中的文本和缓冲区中的文本;
y表示把一个字符翻译为另外的字符(但是不用于正则表达式);
\1子串匹配标记;
&已匹配字符串标记;

sed元字符集

字符说明
^匹配行开始,如:/^sed/匹配所有以sed开头的行;
$匹配行结束,如:/sed$/匹配所有以sed结尾的行;
.匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d;
*匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行;
[]匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed;
[^]匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行;
……匹配子串,保存匹配的字符,如s/(love)able/\1rs,loveable被替换成lovers;
&保存搜索字符用来替换其他字符,如s/love/&/,love这成love;
<匹配单词的开始,如:/\
>匹配单词的结束,如/love>/匹配包含以love结尾的单词的行;
x{m}重复字符x,m次,如:/0{5}/匹配包含5个0的行;

练习:

①#全局替换:g
sed 's/book/books/g' file #/g 标记会替换每一行中的所有匹配
echo sksksksksksk | sed 's/sk/SK/2g' #需要从第N处匹配开始替换时,可以使用 /Ng
[root@zt ~]# echo sksksksksksk | sed 's/sk/SK/2g'            
skSKSKSKSKSK

②#定界符
命令中字符 / 在sed中作为定界符使用,也可以使用任意的定界符
sed 's:test:TEXT:g'     ---> :   :   :
sed 's|test|TEXT|g'   ---> |   |   |
#定界符出现在样式内部时,需要进行转义:
#组合多个表达式
sed 's/\/bin/\/usr\/local\/bin/g'
sed '表达式' | sed '表达式'
sed '表达式; 表达式'

③#删除:d
sed '/^$/d' file #删除空白行
sed '2d' file #删除第二行
sed '2,$d' file #删除第二行到最后一行
sed '$d' file  #删除最后一行
sed '/^test/'d file #删除以test开头的行

④#已匹配字符串标记&
#正则表达式 \w\+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词
[root@zt ~]# echo "this is a test line" | sed 's/\w\+/[&]/g'
[this] [is] [a] [test] [line]

#所有以192.168.0.1开头的行都会被替换成它自已加localhost:
[root@zt ~]# sed 's/^192.168.0.1/&localhost/' file
hello
this is a test line
192.168.0.1localhost

⑤#子串匹配标记\1
#love被标记为1,所有loveable会被替换成lovers,并打印出来
sed -n 's/\(love\)able/\1rs/p' file

[root@zt ~]# echo this is digit 7 in a number | sed 's/digit\([0-9]\)/\1/'
this is digit 7 in a number
[root@zt ~]# echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'
this is 7 in a number
#命令中 digit 7,被替换成了 7。样式匹配到的子串是 7,\(..\) 用于匹配子串,
对于匹配到的第一个子串就标记为 \1,依此类推匹配到的第二个结果就是 \2

[root@zt ~]# echo aaa BBB | sed 's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'
BBB aaa
[root@zt ~]# echo aaa BBB | sed 's/\([a-z]\+\) \([A-Z]\+\)/\1/'
aaa
[root@zt ~]# echo abcd | sed 's/\([a-z]\+\)\([a-z]\+\)\([a-z]\+\)\([a-z]\+\)/\2/'  
b
[root@zt ~]# echo abcd | sed 's/\([a-z]\+\)\([a-z]\+\)\([a-z]\+\)\([a-z]\+\)/\1\2/'
ab

⑥#多点编辑,e
#-e选项允许在同一行里执行多条命令
sed -e '1,5d' -e 's/test/check/' file
#上面sed表达式的第一条命令删除1至5行,第二条命令用check替换test。
命令的执行顺序对结果有影响。如果两个命令都是替换命令,
那么第一个替换命令将影响第二个替换命令的结果

⑦#选定行的范围:,(逗号)
#所有在模板test和check所确定的范围内的行都被打印
sed -n '/test/,/check/p' file
#打印从第5行开始到第一个包含以mail开始的行之间的所有行:
[root@zt ~]# sed -n '5,/^mail/p' /etc/passwd       
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#对于模板test和west之间的行,每行的末尾用字符串aaa bbb替换
sed '/test/,/west/s/$/aaa bbb/' file

⑧#转换:y
#把1~10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令
sed '1,10y/abcde/ABCDE/' file

⑨#从文件读入:r
#file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,
则file的内容将显示在所有匹配行的下面
sed '/test/r file' filename

⑩#写入文件:w
#在example中所有包含test的行都被写入file里
sed -n '/test/w file' example

⑾#追加(行下):a
#将 this is a test line 追加到 以test 开头的行后面
sed '/^test/a\this is a test line' file
sed -i '2a\this is a test line' test.conf #第2行之后插入

⑿#插入(行上)
#i\命令 将 this is a test line 追加到以test开头的行前面
sed '/^test/i\this is a test line' file
sed -i '5i\this is a test line' test.conf

⒀#下一个:n
#如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,
然后继续
sed '/test/{ n; s/aa/bb/; }' file

测试:

1.以行为单位的删除

①将 /etc/passwd 的内容列出并且列印行号,同时,请将第 2~5 行打印出来!

[root@bogon /home/Sudley]#nl /etc/passwd |sed -n '2,5p'

在这里插入图片描述
②删除第 2 行

[root@bogon /home/Sudley]#nl /etc/passwd |sed  '2d'

在这里插入图片描述
③要删除第 3 到最后一行

[root@bogon /home/Sudley]#nl /etc/passwd |sed  '3,$d'

在这里插入图片描述

2.以行为单位的新增

①在第三行后加上newline字样

[root@bogon /home/Sudley]#sed -e 3a\newline testfile

在这里插入图片描述
②在第三行前加上newline字样

[root@bogon /home/Sudley]#sed -e 3i\newline testfile

在这里插入图片描述
③在第二行后面加入两行字,例如newline1 和 newline2

cat testfile|sed -e '2a newline\nnewline2'

在这里插入图片描述

3.以行为单位的替换与显示

①将/etc/passwd中第2-5行的内容取代成为newline

[root@bogon /home/Sudley]#nl /etc/passwd |sed '2,5c newline'

在这里插入图片描述
②搜索 /etc/passwd有root关键字的行

[root@bogon /home/Sudley]#nl /etc/passwd |sed -n '/root/p'

在这里插入图片描述

4.数据的搜寻并删除

①删除/etc/passwd所有包含root的行,其他行输出

[root@bogon /home/Sudley]#nl /etc/passwd |sed '/root/d'

5.数据的搜寻并执行命令

①搜索/etc/passwd,找到root对应的行,把bash替换为blueshell,再输出这行

[root@bogon /home/Sudley]#nl /etc/passwd |sed -n '/root/{s/bash/blueshell/;p;q}'
     1  root:x:0:0:root:/root:/bin/blueshell
[root@bogon /home/Sudley]#p 打印 q 输出 {;;}花括号中间用分号隔开

6.数据的搜寻并替换命令

除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的搜寻并代。
sed 's/要被取代的字串/新的字串/g’
在这里插入图片描述

7.多个命令同时编辑

①一条sed命令,删除/etc/passwd第3行到第五行的数据,并把sbin替换为bin

[root@bogon /home/Sudley]#nl /etc/passwd |sed -e '3,30d' -e 's/sbin/bin/'

在这里插入图片描述

8.直接修改文件内容(危险动作)

sed 可以直接修改文件的内容,不必使用管道命令或数据流重导向! 不过由于这个动作会直接修改到原始的文件,所以千万不要随便拿系统配置来测试!
在这里插入图片描述

9.练习:Week41.config

打印所有生日在十一月或十二月的行

[root@bogon /home/Sudley]#sed -n '/1[12]\//p' week41.config

在这里插入图片描述
在以Kare开头的行末尾加上3颗星

[root@bogon /home/Sudley]#sed -n 's/^Kare.*$/&***/p' week41.config

在这里插入图片描述
将所有包含Jose的行都替换为JOSE HAS RETIRED

[root@bogon /home/Sudley]#sed -n '/Jose/c XXXXX' week41.config

删除所有空行

[root@bogon /home/Sudley]#sed '/^$/d' week41.config

在这里插入图片描述

10.sed扩展延伸版:难度++

/etc/passwd中的练习,为更简洁的表示 只取后三行

[root@bogon /home/Sudley]#cat /etc/passwd |tail -n 3 > testfile
[root@bogon /home/Sudley]#cat testfile
setroubleshoot:x:983:975::/var/lib/setroubleshoot:/sbin/nologin
xguest:x:1002:1002:Guest:/var/lib/xguest/home/xguest:/bin/bash
ipsilon:x:982:974:Ipsilon Server:/var/lib/ipsilon:/sbin/nologin

1.删除文件每行的第一个字符

[root@bogon /home/Sudley]#sed 's/\(.\)\(.*\)/\2/' testfile

在这里插入图片描述
2.删除文件每行的第二个字符

[root@bogon /home/Sudley]#sed 's/\(.\)\(.\)\(.*\)/\1\3/' testfile

3.删除文件每行的第二个单词

[root@bogon /home/Sudley]#sed 's/\([a-Z]\+\)\([^a-Z]\+\)\([a-Z]\+\)\(.*\)/\1\2\4/' testfile

在这里插入图片描述
4.删除文件每行的倒数第二个单词

[root@bogon /home/Sudley]#sed -r 's/(.*)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]*$)/\1\2\4\5/' testfile

在这里插入图片描述
5.交换每行的第一个字符和第二个字符

[root@bogon /home/Sudley]#sed -r 's/(.)(.)(.*)/\2\1\3/' testfile

在这里插入图片描述
6.交换每行的第一个字符和第二个单词

[root@bogon /home/Sudley]#sed 's/\(^[a-Z0-9]\)\([a-Z0-9]*[^a-Z0-9]\{1,\}\)\([a-Z0-9]\{1,\}\)/\3\2\1/g' testfile

在这里插入图片描述
7.交换每行的第一个单词和最后一个单词

[root@bogon /home/Sudley]#sed -r 's/([a-Z]+)([^a-Z]+)(.*)([^a-Z]+)([a-Z]+)([^a-Z]*$)/\5\2\3\4\1\6/' testfile

在这里插入图片描述
8.删除一个文件中所有的数字

[root@bogon /home/Sudley]#sed 's/[0-9]//g' testfile
setroubleshoot:x::::/var/lib/setroubleshoot:/sbin/nologin
xguest:x:::Guest:/var/lib/xguest/home/xguest:/bin/bash
ipsilon:x:::Ipsilon Server:/var/lib/ipsilon:/sbin/nologin

9.删除每行开头的所有空格

[root@bogon /home/Sudley]#sed -r 's/^ +//g' /etc/grub2.cfg

10.用制表符替换文件中出现的所有空格

[root@bogon /home/Sudley]#sed -r 's/ +/\t/g' testfile
setroubleshoot:x:983:975::/var/lib/setroubleshoot:/sbin/nologin
xguest:x:1002:1002:Guest:/var/lib/xguest/home/xguest:/bin/bash
ipsilon:x:982:974:Ipsilon       Server:/var/lib/ipsilon:/sbin/nologin

11.把所有大写字母用括号()括起来

[root@bogon /home/Sudley]#sed -r 's/([A-Z])/(\1)/g' testfile
setroubleshoot:x:983:975::/var/lib/setroubleshoot:/sbin/nologin
xguest:x:1002:1002:(G)uest:/var/lib/xguest/home/xguest:/bin/bash
ipsilon:x:982:974:(I)psilon (S)erver:/var/lib/ipsilon:/sbin/nologin

12.打印每行3次

[root@bogon /home/Sudley]#sed 'p;p' testfile
setroubleshoot:x:983:975::/var/lib/setroubleshoot:/sbin/nologin
setroubleshoot:x:983:975::/var/lib/setroubleshoot:/sbin/nologin
setroubleshoot:x:983:975::/var/lib/setroubleshoot:/sbin/nologin
xguest:x:1002:1002:Guest:/var/lib/xguest/home/xguest:/bin/bash
xguest:x:1002:1002:Guest:/var/lib/xguest/home/xguest:/bin/bash
xguest:x:1002:1002:Guest:/var/lib/xguest/home/xguest:/bin/bash
ipsilon:x:982:974:Ipsilon Server:/var/lib/ipsilon:/sbin/nologin
ipsilon:x:982:974:Ipsilon Server:/var/lib/ipsilon:/sbin/nologin
ipsilon:x:982:974:Ipsilon Server:/var/lib/ipsilon:/sbin/nologin

13.隔行删除

[root@bogon /home/Sudley]#sed '0~2 {=;d}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
2
daemon:x:2:2:daemon:/sbin:/sbin/nologin
4
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@bogon /home/Sudley]#sed '0~3 {=;d}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
3
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
9

14.把文件从第1行到第2行复制到第4行后面

[root@bogon /home/Sudley]#sed '1h;2,2H;4G' testfile

15.只显示每行的第一个单词

[root@bogon /home/Sudley]#sed 's/\([a-Z]\+\)\([^a-Z]\+\)\(.*\)/\1/' testfile
ipsilon
setroubleshoot
xguest

16.将格式为 mm/yy/dd 的日期格式换成 mm-yy-dd

[root@bogon /home/Sudley]#date '+%m/%y/%d' |sed 's#/#-#g'
08-19-06

17.去掉ssh配置文件中的带#行和空行

[root@bogon /home/Sudley]#sed 's/#.*$//g' /etc/ssh/sshd_config | sed '/^$/d'
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile      .ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
UsePrivilegeSeparation sandbox
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem       sftp    /usr/libexec/openssh/sftp-server
[root@bogon /home/Sudley]#

grep命令——Linux三剑客(一)
awk命令——Linux三剑客(三)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值