15 The sed command of the Three Musketeers

The sed command of the Three Musketeers

A sed introduction

​ The full name of sed (stream editor) is a stream editor. Sed is mainly used to automatically edit one or more files, simplify repeated operations on files, write conversion programs, etc. The workflow is as follows

sed 是一种在线的、非交互式的编辑器,它一次处理一行内容。处理时,把当前处理的行存储在
临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完
成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有
改变,除非你使用重定向存储输出,或者使用sed -i选项
-i选项就是将本该输出到屏幕上的内容输出/流入文件中

​ The sed command format is as follows

sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

# 注:
sed和grep不一样,不管是否找到指定的模式,它的退出状态都是0
只有当命令存在语法错误时,sed的退出状态才不是0

Two sed options and basic usage examples

###2.1 sed option

选项			   功能
-e				允许多项编辑
-n				取消默认的输出(模式空间的内容输出)
-i				inplace,就地编辑
-r				支持扩展元字符
-f				指定sed脚本文件名

示例
# sed -r '' /etc/passwd
# sed -r 'p' /etc/passwd
# sed -r -n 'p' /etc/passwd	


文件的一行行内容相当与水流,连续两个-e就是设置了两道关卡
[root@aliyun ~]# sed '' test.txt 
1111111
2222222egon
333333egon
444444egon
555555eon
[root@aliyun ~]# sed -e '3d' -e '1d' test.txt  
2222222egon
444444egon
555555eon
[root@aliyun ~]# sed -rn -e '1,3d' -e 'p' test.txt
444444egon
555555eon
[root@aliyun ~]# 

也可以将多道关卡写入一个文件中
[root@aliyun ~]# cat sed.txt 
1,3d
p
[root@aliyun ~]# sed -rn -f sed.txt test.txt
444444egon
555555eon
[root@aliyun ~]# 

###2.2 sed command composition

The command is composed of "address + command" two parts, commands such as p, d, more detailed in Chapter 3, this section we mainly introduce the address

The address is used to determine which lines flow into the pattern space to edit. If no address is specified, sed will process all lines that flow into the pattern space.

Address can be

  • 1. Numbers

    sed -n 'p' /etc/passwd	
    sed -n '1,3p' /etc/passwd	
    sed '1,47d' /etc/passwd
    
  • 2. Regular expressions

    与grep一样,sed在文件中查找模式时也可以使用正则表达式(RE)和各种元字符。正则表达式是
    括在斜杠间的模式,用于查找和替换,以下是sed支持的元字符。
    
    # 使用基本元字符集	
    ^, $, ., *, [], [^], \< \>,\(\),\{
          
          \}
    
    # 使用扩展元字符集	
    ?, +, {
          
           }, |, ( )
    
    # 使用扩展元字符的方式:
    转义,如\+
    -r参数,如sed -r
    
    [root@aliyun ~]# cat test.txt 
    1111111
    2222222egon
    333333egon
    444444egon
    555555eon
    [root@aliyun ~]# sed -rn '/egon/p' test.txt 
    2222222egon
    333333egon
    444444egon
    [root@aliyun ~]# 
    
  • 3. Number + regular expression

    [root@aliyun ~]# cat test.txt 
    1111111
    2222222egon
    333333egon
    444444egon
    555555eon
    [root@aliyun ~]# sed -rn '1,/egon/p' test.txt 
    1111111
    2222222egon
    [root@aliyun ~]# 
    
    解释:
    # "1,8p"代表打印1到8行,"1,/egon/p"则代表取从第1行到首次匹配到/egon/的行
    

2.3 \cregexpc

The address can be a regular expression, and the regular expression needs to be placed between \c and c, where c can be any character, but \ must be escaped

[root@aliyun ~]# cat test.txt 
1111111
2222222egon
333333egon
444444egon
555555eon
[root@aliyun ~]# sed -rn '#egon#p' test.txt 
[root@aliyun ~]# sed -rn '\#egon#p' test.txt 
2222222egon
333333egon
444444egon
[root@aliyun ~]# 

If c is a left slash, it does not need to be escaped

[root@aliyun ~]# sed -rn '\/egon/p' test.txt 
2222222egon
333333egon
444444egon
[root@aliyun ~]# sed -rn '/egon/p' test.txt 
2222222egon
333333egon
444444egon
[root@aliyun ~]# 

If there is a left slash in the matched regular, either the regular is escaped, or c is escaped

[root@aliyun ~]# cat a.txt 
/etc/egon/666
etc
[root@aliyun ~]# sed -rn '//etc/egon/666/p' a.txt # 错误
sed: -e expression #1, char 0: no previous regular expression
    
[root@aliyun ~]# sed -rn '/\/etc\/egon\/666/p' a.txt  # 正则转义
/etc/egon/666

[root@aliyun ~]# sed -rn '#/etc/egon/666#p' a.txt # 转义c,必须是\c
[root@aliyun ~]# sed -rn '\#/etc/egon/666#p' a.txt  # 转义c
/etc/egon/666
[root@aliyun ~]# 


# 示例
[root@aliyun ~]# cat a.txt 
/etc/egon/666
etc
[root@aliyun ~]# sed -ri '/\/etc\/egon\/666/s/.*/xxx/' a.txt 
[root@aliyun ~]# cat a.txt 
xxx
etc
[root@aliyun ~]# 

Three common sed commands

The sed command tells sed what operations to perform on the specified line, including printing, deleting, and modifying.

命令			   功能
a				在当前行后添加一行或多行
c				用新文本修改(替换)当前行中的文本
d				删除行
i				在当前行之前插入文本
l				会用$符号标识出文件中看不到的字符的位置
p				打印行
n				把下一行内容读入模式空间,后续的处理命令处理的都是刚读入的新内容
q				结束或退出sed,不会将后续内容读入模式空间
r				从文件中读
!				对所选行以外的所有行应用命令
s				用一个字符串替换另一个
w				将行写入文件
y				将字符转换为另一字符(不支持正则表达式),y/egon/1234/  e->1 g->2 o->3 n->4

h				把模式空间里的内容复制到暂存缓冲区(覆盖)
H				把模式空间里的内容追加到暂存缓冲区
g				取出暂存缓冲区的内容,将其复制到模式空间,覆盖该处原有内容
G				取出暂存缓冲区的内容,将其复制到模式空间,追加在原有内容后面
x				交换暂存缓冲区与模式空间的内容

替换标志 s
g				在行内进行全局替换
i				忽略大小写

sed command example

打印命令:p
# sed -r "/egon/p" a.txt		
# sed -r -n "/egon/p" a.txt

删除命令:d,注意用单引号
# sed -r '3d' a.txt
# sed -r '3,$d' a.txt
# sed -r '$d' a.txt
# sed -r '/egon/d' a.txt 	
# sed -r '1,/egon/{/egon/d}' a.txt 		



#需求:请实现删除以#注释开头的行和空行 在b.txt文件里 用到了/^#|^$/表示
[root@web01 ~]# sed -r '/^#|^$/d' b.txt
111uuuuuu
wwww33333
4uuuuuuuu
[root@web01 ~]# sed -r '' b.txt
111uuuuuu
#222uuuuuu
wwww33333
4uuuuuuuu

##5dd//dddddd
##6666//44444


	# 只删除模式匹配成功的第一行


[root@egon ~]# cat a.txt 
Egon111111
egon222222
333Egon333
444444egon
5555555555
6666666666
egon777777
8888888888
[root@egon ~]# 
[root@egon ~]# sed -r '/egon/d' a.txt  # 只删除模式匹配成功的所有行
Egon111111
333Egon333
5555555555
6666666666
8888888888
[root@egon ~]# sed -r '1,/egon/{/egon/d}' a.txt  # 只删除模式匹配成功的第一行
Egon111111
333Egon333
444444egon
5555555555
6666666666
egon777777
8888888888


替换命令:s
# sed -r 's/egon/Bigegon/' a.txt 
# sed -r 's/egon/Bigegon/g' a.txt 
# sed -r 's/^egon/Bigegon/g' a.txt
# sed -r -n 's/root/egon/gip' /etc/passwd
# sed -r 's/[0-9]$/&.change/' a.txt		# &代表取到匹配成功的整行内容

# sed -r 's/^([a-zA-Z]+)([^[a-zA-Z]+)/\2\1/' a.txt
# sed -r 's#egon#bigegon#g' a.txt			

多重编辑命令:e
# sed -r -e '1,3d' -e 's/[Ee]gon/EGON/g' a.txt  # 在前一个-e的基础之上进行第二个-e操作
# sed -r '1,3d;s/[Ee]gon/EGON/g' a.txt

# sed -r '3{s/[0-9]/x/g;s/[Ee]gon/EGON/g}' a.txt  # 只处理第三行
# sed -r '1,3{s/[0-9]/x/g;s/[Ee]gon/EGON/g}' a.txt  # 处理1到3行

# sed -r -n '1p;p' a.txt  # ;分隔依次运行,先针对第一行进行p操作,再针对所有行进行p操作
# sed -r -n '1{p;p}' a.txt  # 只针对第一行,连续进行两次p操作

反向选择!
# sed -r '3d' a.txt
# sed -r '3!d' a.txt


读文件命令:r
# sed -r '/^Egon/r b.txt' a.txt  # 在匹配成功的行后添加文件b.txt的内容
# sed -r '2r b.txt' a.txt  # 在第2行后面添加文件b.txt的内容

写文件命令:w
# sed -r '/[Ee]gon/w b.txt' a.txt  # 将匹配成功的行写入新文件b.txt		
# sed -r '3,$w /root/new.txt' a.txt # 将第3行到最后一行写入/root/new.txt

追加命令:a
# sed -r '2aXXXXXXXXXXXXXXXXXXXX' a.txt  # 在第2行后添加一行
# sed -r '2a1111111111111\               # 可以用\续行
> 222222222222\
> 333333333333' a.txt

插入命令:i
# sed -r '2i1111111111111' /etc/hosts
# sed -r '2i111111111\
> 2222222222\
> 3333333333' a.txt

修改命令:c
# sed -r '2c1111111111111' a.txt
# sed -r '2c111111111111\
> 22222222222\
> 33333333333' a.txt

把下一行内容读入模式空间:n
# sed -r '/^Egon/{n;s/[0-9]/x/g}' a.txt  # 将匹配/^Egon/成功的行的下一行读入模式空间进行s处理
[root@aliyun ~]# cat a.txt 
/etc/egon/666
etc
[root@aliyun ~]# sed -r '\#/etc/egon/666#n;c 1111' a.txt 
/etc/egon/666
1111
[root@aliyun ~]# 

转换命令:y
# sed -r '1,3y/Eeo/12X/' a.txt  # 1到3行进行转换 对应规则:a->1 e->2 o->X

退出:q
# sed -r '5q' a.txt 			
# sed -r '/[Ee]gon/{ s/[0-9]/X/; q; }' a.txt  # 匹配成功/[Ee]gon/则执行{}内命令,q代表退出,即替换一次则退出,如果文件中多行符合规则的内容也只替换了第一个

Four-mode space and holding space

sed has two built-in storage spaces:

  • Pattern space:

    As you know, the pattern space is used in the normal flow of sed execution. A buffer in the space sed is used to store and modify the content read from the input file.

  • Hold space:

    The holding space is another buffer area for storing temporary data. Sed can exchange data between the holding space and the pattern space, but cannot execute ordinary sed commands in the holding space.

We have already discussed that the contents of the pattern space will be emptied every time the data is read in a loop, but the contents of the hold space will remain unchanged and will not be deleted in the loop.

Operation commands for pattern space and hold space

x:命令x(exchange) 用于交换模式空间和保持空间的内容

h:模式空间复制/覆盖到保持空间
H:模式空间追加到保持空间

g:保持空间复制/覆盖到模式空间
G:保持空间追加到模式空间

n:读取下一行到/覆盖到模式空间
N:将下一行添加到模式空间


d:删除pattern space中的所有行,并读入下一新行到pattern space中

Example: swap file lines

[root@egon ~]# cat test.txt 
1111
2222
3333

# ======================方式1:======================
[root@egon ~]# tac test.txt 
3333
2222
1111
[root@egon ~]# 

# ======================方式2:======================
思路:
# 1、读取文件第一行内容到模式空间,进行的操作如下  
# 将模式空间内容覆盖到保持空间
# 删除模式空间内容
   
# 2、读取文件第二行内容到模式空间,进行的操作如下  
# 将保持内容追加到模式空间
# 将模式空间内容覆盖到保持空间
# 删除模式空间内容 

# 3、读取文件第三行内容到模式空间,进行的操作如下  
# 将保持空间内容追加到模式空间

实现:
sed -r '1h;1d;2G;2h;2d;3G' test.txt
或者
sed '1!G;h;$!d' test.txt

Five sed scripts

The sed script is a series of sed commands written in the file. Use the -f option to specify the sed script file name. The issues that need to be paid attention to are as follows

  • There can be no extra spaces or text at the end of the script
  • If the command cannot be on its own line, it must end with \
  • Quotation marks cannot be used in scripts unless they are part of the search string
  • The backslash acts as a continuation line
[root@egon ~]# cat sed.sh #永久存储,存了多行sed命令,相当于多道关卡,每读入一行内容将经历一道道关卡
1h;1d;2G;2h;2d;3G
1h;1d;2G;2h;2d;3G

[root@egon ~]# sed -r '' a.txt
1111
2222
3333
[root@egon ~]# 
[root@egon ~]# sed -r -f sed.sh test.txt 
3333
2222
1111
2222
1111
[root@egon ~]# 

Six exercises


删除配置文件中用井号#注释的行
sed -r -i '/^#/d' file.conf 
sed -r -i '/^[ \t]*#/d' file.conf

删除配置文件中用双斜杠//注释的行 
sed -r -i '\c//cd' file.conf

删除无内容空行 
sed -r '/^$/d' file.conf 
sed -r '/^[\t]*$/d' file.conf 
sed -r '/^[ \t]*$/d' file.conf


示例:
# 删除#号注释和无内容的空行
sed -r -i '/^[ \t]*#/d; /^[ \t]*$/d' /etc/vsftpd/vsftpd.conf
sed -r -i '/^[ \t]*#|^[ \t]*$/d' /etc/vsftpd/vsftpd.conf # 同上

追加一行,\可有可无,有更清晰
sed -r -i '$a\chroot_local_user=YES' /etc/vsftpd/vsftpd.conf 


给文件每行加注释
sed -r -i 's/^/#/' filename

每指定行加注释
sed -r -i '10,$s/^/#/' filename
sed -r '3,$s/^#*/#/' filename		# 将行首连续的零个或多个#换成一个#


sed中使用外部变量
# var1=666
# sed -r 3a$var1 test.txt    # 可以不加引号
# sed -r "3a$var1" test.txt  # 也可以加引号,但注意是双引号而不是单引号,因为要用$符号取变量值
# sed -r '3a'"$var1" test.txt # 也可以sed命令用''引起来,而变量用"",注意二者之间不能有空格

Guess you like

Origin blog.csdn.net/ximanxue/article/details/112793296