sed语句进阶
sed能查看模式空间的多个行,这就是允许匹配模式扩展到多行上,3个多行命令(N、D、P))对应于小 写字母的基本命令(n、d、p)。例如,删除命令(D)是删除命令(d)的多行形式。区别是:d删除模 式空间的内容,D只删除多行模式空间的第一行。
命令 功能
a增加,在匹配到那行下面增加一行内容
i插入,在匹配到那行上面插入一行内容
c更改,在匹配到的那行,进行更改
d删除,将匹配到的那行,进行删除
Delete(D) 删除多行模式空间中的首行
p打印配到哪一行,sed默认有打印功能,所以一般配合-n使用
Print(P) 打印多行组中的一行。
n 打印当前模式空间内容,然后读取下一行并替代当前模式空间的内容。如果读取不到下一行sed则会不运行之后的命令
Next (N) 追加读取匹配到的行的下一行至模式空间中
h(hold) 将模式空间中的内容复制到保持空间
H(Hold) 将模式空间中的内容附加到保持空间
g 将保持空间中的内容复制到模式空间
G(Get) 将保持空间中的内容附加到模式空间
x(Exchange) 交换模式空间和保持空间中的内容
d:删除
[root@localhost ~]# cat anaconda-ks.cfg #version=RHEL8 # Use graphical install graphical # 删除此行 repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream [root@localhost ~]# sed '/^graphical/d' anaconda-ks.cfg # 精准匹配到删除 #version=RHEL8 # Use graphical install #原本在下面的删除掉了 repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream %packages @^minimal-environment kexec-tools
[root@localhost ~]# cat anaconda-ks.cfg -n #查看行号 1 #version=RHEL8 2 # Use graphical install 3 graphical # 第三行 4 5 repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream 6 7 %packages 8 @^minimal-environment [root@localhost ~]# sed '3d' anaconda-ks.cfg #利用行号删除 #version=RHEL8 # Use graphical install repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream %packages @^minimal-environment kexec-tools
替换元字符
[root@localhost ~]# echo '/usr/local/src' | sed 's/\/usr\/local\/src/\/user\/local\/src/' # 路径的斜杠每一个都要加转义符很麻烦 /user/local/src [root@localhost ~]# echo '/usr/local/src' | sed 's#/usr/local/src#/user/local/src#' # 可以用#代替 /user/local/src [root@localhost ~]# echo '/usr/local/src' | sed 's!/usr/local/src!/user/local/src!' #也可以用!代替 /user/local/src
. 表示一个正真的制表符,而制表符在屏幕上是看不到的,如果输入一行文件如下所示:
[root@localhost ~]# vi abc [root@localhost ~]# cat abc Column1 Column2 Column3 Column4 [root@localhost ~]# sed 's/\t/>/2' abc #\t是制表符,把第二个换成> Column1 Column2>Column3 Column4 [root@localhost ~]# sed 's/\t/\ # 第二个制表符换行 > /2' abc Column1 Column2 Column3 Column4 [root@localhost ~]# sed 's/\t/\n/2' abc #效果同上 Column1 Column2 Column3 Column4
[root@localhost ~]# echo '.Ah "Major Heading"' > abc [root@localhost ~]# cat abc .Ah "Major Heading" [root@localhost ~]# sed '/^\.Ah/{ #匹配.A和开头的 > s/\.Ah */\ #替换.Ah开头的然后换行 > \ #在换行 > @A HEAD = / # 换成@A HEAD = > s/"//g # 把引号替换成空的 > s/$/\ #把这个$替换然后换行 > / > } ' abc # 更上文件文件名 @A HEAD = Major Heading #效果
[root@localhost ~]# sed '/^\.Ah/{s/\.Ah */\n@A HEAD = /;s/"//g};s/$/\n/' abc
@A HEAD = Major Heading
[root@localhost ~]#
[root@localhost ~]# vi abc [root@localhost ~]# cat abc .Ah "Major Heading" ORA Associates, Inc. [root@localhost ~]# sed "s/ORA/O' Reilly \&/" abc #匹配到ORA替换成O' Reilly &,&有特殊意义,所以要加转义符 .Ah "Major Heading" O' Reilly & Associates, Inc.
[root@localhost ~]# cat abc .Ah "Major Heading" ORA Associates, Inc. on the UNIX Operating Systen. [root@localhost ~]# sed 's/UNIX/\\s-2&\\s0/g' abc #匹配到的UNIX的前面加上\s-2 在前面加就是在&前面写,在后面就在&后面写 .Ah "Major Heading" ORA Associates, Inc. on the \s-2UNIX\s0 Operating Systen.
[root@localhost ~]# vi abc [root@localhost ~]# cat abc .Ah "Major Heading" ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 [root@localhost ~]# sed 's/See Section [1-9][0-9]*\.[1-9][0-9]*/(&)/g'abc # *表示前面的0-9可以出现任意次,点加上转义符,就是.本身,括号把&扩起来就是把整行内容扩起来 .Ah "Major Heading" ORA Associates, Inc. on the UNIX Operating Systen. (See Section 1.4) (See Section 12.9) [root@localhost ~]# sed -r 's/(See Section) ([1-9][0-9]*\.[1-9][0-9]*)/\1\\fb\2\\fp/g' abc # 用括号把See Section括起来,把数字也括起来,后面\1先打印出来,然后\2代表的是数字然后在前面后面替换上内容 .Ah "Major Heading" ORA Associates, Inc. on the UNIX Operating Systen. See Section\fb1.4\fp See Section\fb12.9\fp
[root@localhost ~]# cat abc .Ah "Major Heading" ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 first:second one:two [root@localhost ~]# sed -r 's/(.*):(.*)/\2:\1/g' abc # 第一个.*匹配到的是:前面的内容\1表示,第2个.*匹配到的是:后面的内容\2表示。把\2的内容放到前面,\1的放到后面,-r是正则表达式 .Ah "Major Heading" ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 second:first two:one
删除d
[root@localhost ~]# cat abc .Ah "Major Heading" ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 first:second one:two [root@localhost ~]# sed '/^\.Ah/d' abc # 匹配到.Ah开头的删除 ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 first:second one:two
追加(a)插入(i)修改(c)
a追加 [root@localhost ~]# sed '1aass' abc # 在第1行后面加入ass .Ah "Major Heading" ass aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 first:second one:two [root@localhost ~]# sed '1 a ass' abc # 在内容前面加空格,下面的显示也没有 .Ah "Major Heading" ass aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 first:second one:two [root@localhost ~]# sed '1a " ass"' abc # 把加入的内容引起来,就会有了 .Ah "Major Heading" " ass" aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 first:second one:two [root@localhost ~]# sed '1a \ ass' abc # 用转义符也可以 .Ah "Major Heading" ass aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 first:second one:two
[root@localhost ~]# sed '/^See/a 123' abc #匹配的See哪两行然后追加
.Ah "Major Heading"
aAh fvgerbevdve
ORA Associates, Inc.
on the UNIX Operating Systen.
See Section 1.4
123
See Section 12.9
123
first:second
one:two
[root@localhost ~]# cat abc
.Ah "Major Heading"
aAh fvgerbevdve
ORA Associates, Inc.
on the UNIX Operating Systen.
See Section 1.4
See Section 12.9
See Section 13.5
first:second
one:two
[root@localhost ~]# sed '/See.*[1-9][0-9]\.[0-9]/aabc' abc # 精确匹配到这两行加入内容
.Ah "Major Heading"
aAh fvgerbevdve
ORA Associates, Inc.
on the UNIX Operating Systen.
See Section 1.4
See Section 12.9
abc
See Section 13.5
abc
first:second
one:two
i插入 [root@localhost ~]# sed '1ihehe' abc # 在第一行插入内容,插入的内容就变成第一行了 hehe .Ah "Major Heading" aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 See Section 13.5 first:second one:two [root@localhost ~]# sed '/^\.Ah/i abc' abc #匹配到.Ah的这行插入内容 abc .Ah "Major Heading" aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 See Section 13.5 first:second one:two [root@localhost ~]# sed '/See.*[1-9][0-9]\.[0-9]/i abc' abc #也可以精确匹配到这两行插入 .Ah "Major Heading" aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 abc See Section 12.9 abc See Section 13.5 first:second one:two
c更改 [root@localhost ~]# cat abc .Ah "Major Heading" aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 See Section 13.5 first:second one:two [root@localhost ~]# sed '1c hehe' abc #第一行被修改为hehe hehe aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 See Section 13.5 first:second one:two [root@localhost ~]# sed '/aAh/c \xixi' abc #匹配到aAh的这行更改为xixi .Ah "Major Heading" xixi ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 See Section 13.5 first:second one:two [root@localhost ~]# sed '/^\.Ah/iabc\ hehe' abc abc hehe .Ah "Major Heading" aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 See Section 13.5 first:second one:two
[root@localhost ~]# sed '/^\.Ah/,/on /cabc' abc #匹配.Ah开头的这行到最近的on开头的这行的内容修改成abc
abc
See Section 1.4
See Section 12.9
See Section 13.5
first:second
one:two
[root@localhost ~]# sed '/^\.Ah/,$c abc' abc #匹配所有的更改为abc
abc
转换
[root@localhost ~]# cat abc .Ah "Major Heading" aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 See Section 13.5 first:second one:two [root@localhost ~]# sed '1y/ajo/123/' abc #把第一行里面的ajo转换成123 .Ah "M123r He1ding" aAh fvgerbevdve ORA Associates, Inc. on the UNIX Operating Systen. See Section 1.4 See Section 12.9 See Section 13.5 first:second one:two
打印
[root@localhost ~]# sed '/^\.Ah/{p;s/"//g;s/^\.Ah //}' 2 # 匹配到.Ah的行,先p打印,然后把"换成空,匹配.Ah换成空并打印 .Ah "Comment" Comment .Ah "Substitution" Substitution .Ah "Delete" Delete .Ah "Append, Insert and Change" Append, Insert and Change .Ah "List" List
打印行号
[root@localhost ~]# sed '/Comment/{=;p}' 2 1 .Ah "Comment" .Ah "Comment" .Ah "Substitution" .Ah "Delete" .Ah "Append, Insert and Change" .Ah "List" [root@localhost ~]# sed -n '/Comment/{=;p}' 2 1 .Ah "Comment" [root@localhost ~]#
下一步
[root@localhost ~]# cat 2 .Ah "Comment" .Ah "Substitution" .Ah "Delete" .Ah "Append, Insert and Change" .Ah "List" [root@localhost ~]# sed -n '/Comment/n;p' 2 #没有打印Comment,从他的下一个开始打印的 .Ah "Substitution" .Ah "Delete" .Ah "Append, Insert and Change" .Ah "List" [root@localhost ~]# cat 2 .Ah "Comment" .Ah "Substitution" .Ah "Delete" .Ah "Append, Insert and Change" .Ah "List" [root@localhost ~]# sed -r '/Comment/{n;s/\.Ah (.*)/\.Ah (\1)/g}' 2 # Comment下一个以.Ah开头的用括号扩起来 .Ah "Comment" .Ah ("Substitution") .Ah "Delete" .Ah "Append, Insert and Change" .Ah "List" [root@localhost ~]# cat 2 .Ah "Comment" .Ah "Substitution" .Ah "Delete" .Ah "Comment" .Ah "Append, Insert and Change" .Ah "Comment" .Ah "List" [root@localhost ~]# sed -r '/Comment/{n;s/\.Ah (.*)/\.Ah (\1)/g}' 2 .Ah "Comment" .Ah ("Substitution") .Ah "Delete" .Ah "Comment" .Ah ("Append, Insert and Change") .Ah "Comment" .Ah ("List") [root@localhost ~]# cat 2 .Ah "Comment" .Ah "Substitution" .Ah "Delete" .Ah "Comment" .Ah "Append, Insert and Change" .Ah "Comment" .Ah "List" [root@localhost ~]# sed '/Comment/{n;/^$/d}' 2 # 匹配到Comment下一行,如果是空行就删掉 .Ah "Comment" .Ah "Substitution" .Ah "Delete" .Ah "Comment" .Ah "Append, Insert and Change" .Ah "Comment" .Ah "List"
sed高级用法
1处理多行模式空间(N,D,P)
2采用保持空间来保存莫斯空间的内容并使他可以用于后续的命令(H,h,G,g,x)
多行模式空间:模式空间可以想象成一个作坊,对文本进行处理,保存空间就可以比作为一个仓库,用于存放在模式空间处理完之后的文本存放的地方。
N追加下一行
[root@localhost ~]# cat abc #原文件 Consult Section 3.1 in the Owner and Operator Guide for a description of the tape drives available on your system. [root@localhost ~]# sed -n '/Operator$/{N;p}' abc # 匹配到这两行 Consult Section 3.1 in the Owner and Operator Guide for a description of the tape drives [root@localhost ~]# sed -n '/Operator$/{N;s/Owner and Operator\nGuide/Installtion Guide/g;p}' abc # 匹配到这两行,然后替换把Owner and Operator和Guide也包括换行用\n表示换成Installtion Guide Consult Section 3.1 in the Installtion Guide for a description of the tape drives # 打印的结果应为把换行替换掉了,所以就是一行 [root@localhost ~]# sed '/Operator$/{N;s/Owner and Operator\nGuide/Installtion Guide/g}' abc #取消打印执行 Consult Section 3.1 in the Installtion Guide for a description of the tape drives available on your system. [root@localhost ~]# cat abc #原文本 Consult Section 3.1 in the Owner and Operator Guide for a description of the tape drives avai lable on your system. Look in the Owner and Operator Guide shipped with your system. Two manuals are provided inc luding the Owner and Operator Guide and the User Guide. The Owner and Operator Guide is shipped with your system. [root@localhost ~]# sed 's/Owner and Operator Guide/Installtion Guide/g' abc # 把文本里的Owner and Operator Guide替换成Installtion Guide Consult Section 3.1 in the Owner and Operator Guide for a description of the tape drives avai lable on your system. Look in the Installtion Guide shipped with your system. Two manuals are provided inc luding the Owner and Operator Guide and the User Guide. The Installtion Guide is shipped with your system. [root@localhost ~]# sed -n 's/Owner and Operator Guide/Installtion Guide/g;/Owner/{N;p}' abc # # 把文本里的Owner and Operator Guide替换成Installtion Guide,打印Owner和他的下一行,此时打印的是模式空间的内容 Consult Section 3.1 in the Owner and Operator Guide for a description of the tape drives Two manuals are provided inc luding the Owner and Operator Guide and the User Guide. [root@localhost ~]# sed -n 's/Owner and Operator Guide/Installtion Guide/g;/Owner/{N;s/ *\n/ /p}' abc #前面步骤同上,把换行替换成一给空格,4行变2行 Consult Section 3.1 in the Owner and Operator Guide for a description of the tape drives Two manuals are provided inc luding the Owner and Operator Guide and the User Guide. [root@localhost ~]# sed -n 's/Owner and Operator Guide/Installtion Guide/g;/Owner/{N;s/ *\n/ /;s/Owner and Operator Guide */Installtion Guide\n/g;p}' abc # 把Owner and Operator Guide替换成Installtion Guide\n 后面要换行一行变两行 Consult Section 3.1 in the Installtion Guide for a description of the tape drives Two manuals are provided inc luding the Installtion Guide and the User Guide. [root@localhost ~]# echo 's/Owner and Operator Guide/Installtion Guide/g;/Owner/{N;s/ *\n/ /;s/Owner and Operator Guide */Installtion Guide\n/g;p}' > test #单行变多行把一整行写到test文件 [root@localhost ~]# vim test s/Owner and Operator Guide/Installtion Guide/ #替换内容 g/Owner/{ #匹配Owner的两行 N #加上匹配到两行的下面一行 s/ *\n/ / # 换成替换成空格 s/Owner and Operator Guide */Installtion Guide\ #替换内容,后面的内容有换行 /g } [root@localhost ~]# sed -f test abc #执行效果和一行的是一样的 Consult Section 3.1 in the Installtion Guide for a description of the tape drives avai lable on your system. Look in the Installtion Guide shipped with your system. Two manuals are provided inc luding the Installtion Guide and the User Guide. The Installtion Guide is shipped with your system.
D删除模式空间第一行
[root@localhost ~]# cat abc # 原文本 This line is followed by 1 blank line. This line is followed by 2 blank lines. This line is followed by 3 blank lines. This line is followed by 4 blank lines. This is the end. [root@localhost ~]# sed -n '/^$/{N;p}' abc #匹配空行和空行下面的内容 This line is followed by 2 blank lines. # 1只有一个空行所以不满足条件,匹配不到 This line is followed by 4 blank lines. # 3空行数是基数所以也匹配不到 能被匹配到的是2和4,最后一行上面4个空行都被匹配到,所以最后一行也不满足匹配要求 [root@localhost ~]# sed -n '/^$/{N;/^\n$/d;p}' abc #在以上基础上,以换行结尾的匹配两个空行,第一行空行不满足条件,不匹配,字符也不满足,带2的字符串下面第12行34行空行满足匹配删除,第5行空行不满足,带4的字符串不满足,下面的第12行,34行满足,匹配删除, This line is followed by 2 blank lines. This line is followed by 4 blank lines. [root@localhost ~]# sed '/^$/{N;/^\n$/d}' abc This line is followed by 1 blank line. # 1下面就一个空行不满足保留 This line is followed by 2 blank lines. #2下面2个空行匹配删除 This line is followed by 3 blank lines. #3下面3个空行,匹配到两个删除保留一个 This line is followed by 4 blank lines. # 4下面4个空行匹配到两次,都删除 This is the end. #偶数行的全删,基数行的保留一行
P多行打印:只打印模式空间的第一行
[root@localhost ~]# cat abc # 原文件 Here are examples of the UNIX System. Where UNIX System appears,it should be the UNIX Operat ing System. [root@localhost ~]# sed -n '/UNIX$/p' abc #匹配UNIX结尾的打印 System. Where UNIX System appears,it should be the UNIX #下一行一打印出来 [root@localhost ~]# sed -n '/UNIX$/{N;p}' abc Here are examples of the UNIX System. Where UNIX System appears,it should be the UNIX Operat ing System. [root@localhost ~]# sed -n '/UNIX$/{N;/\nSystem/{p}}' abc #在以上基础上在匹配换行System Here are examples of the UNIX System. Where UNIX [root@localhost ~]# sed -n '/UNIX$/{N;/\nSystem/{s// Operating &/;p}}' abc # 上面基础上UNIX后加上Operating Here are examples of the UNIX Operating System. Where UNIX [root@localhost ~]# sed -n '/UNIX$/{N;/\nSystem/{s// Operating &/g;P;D;p}}' abc #加上P.打印模式空间第一行,又被D删除模式空间第一行给删除了,又去从新匹配又有了Here are examples of the UNIX Operating然后打印 Here are examples of the UNIX Operating System. Where UNIX Operating [root@localhost ~]# sed '/UNIX$/{N;/\nSystem/{s// Operating &/g;P;D}}' abc #执行结果 Here are examples of the UNIX Operating System. Where UNIX Operating System appears,it should be the UNIX Operat ing System.
包含哪一行
命令 | 缩写 | 功能 |
---|---|---|
Hold | h或H | 将模式空间的内容复制或追加到保持空间 |
Get | g或G | 将保持空间的内容复制或追加到模式空间 |
Exchange | x | 交换保持空间和模式空间的内容 |
将模式空间的内容复制或追加到保持空间,复制会覆盖掉内容,追加是原基础上增加内容
[root@localhost ~]# cat abc 1 2 11 22 111 222 [root@localhost ~]# sed -n '/1/p' abc #匹配1 1 11 111 [root@localhost ~]# sed '/1/{h;d};/2/{G}' abc #1匹配到1,11,111,放到保持空间,把模式空间删除掉,然后匹配2,匹配到2,22,222,此时模式空间只有2,1都没了删除掉了G把保持空间的1都追加到模式空间2后面 2 1 22 11 222 111
y替换大小写
[root@localhost ~]# cat abc find the Match statement Consult the Get statement. Using the Read statement to retrieve data [root@localhost ~]# sed -rn '/the .* statement/{h;s/.*the(.*)statement.*/\1/;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G;s/(.*)\n(.*the).*(statement.*)/\2\1\3/;p}' abc #使用扩展正则表达式,匹配the statement中间有其他字符串的行,复制到模式空间1位子替换成大写替换成大写,追加到模式空间,然后替换位子把1放到中间 find the MATCH statement Consult the GET statement. Using the READ statement to retrieve data
awk
[root@localhost ~]# echo 'this line of data is ignored.' > abc #写一行到abc [root@localhost ~]# awk '{print "hello world"}' abc # 用引号把hello world引起来没有用$几,所以打印hello world hello world [root@localhost ~]# echo '' >> abc #追加一个空行 [root@localhost ~]# awk '{print "hello world"}' abc #打印两次 hello world hello world [root@localhost ~]# cat abc #打印几次取决有记行 this line of data is ignored. [root@localhost ~]# awk 'BEGIN{print "hello world"}' #BEGIN表示开始 hello world [root@localhost ~]# echo '' >> abc #在追加两个空行 [root@localhost ~]# echo '' >> abc [root@localhost ~]# cat abc this line of data is ignored. [root@localhost ~]# awk '/^$/{print "hello world"}' abc #匹配空行有几个就打印几个hello world hello world hello world hello world [root@localhost ~]# echo 'a b c d'|awk 'BEGIN{one = 1; two = 2 }{print $(one + two)}' #one等于1two等于2,打印1+2的结果所以是第三列就是c c
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通