sed 文本处理

语法

sed [选项] [命令] [输入文件]

选项

-n :仅打印模式匹配的行,常与 p 搭配使用
-e :可进行多项编辑,即可对输入行使用多条 sed 命令,默认选项
-f :将 sed 的动作写在一个脚本文件内,用 -f filename 参数执行 filename 内的 sed 动作
-r :支持扩展表达式
-i :直接修改文件内容,如 sed -i 's/old/new/g' demo.txt

命令

a \text:append 在指定行后追加文本 text,支持使用 \n 实现多行追加;
i \text :insert 在指定行前插入文本 text,支持使用 \n 实现多行插入
c \text:将指定行的内容替换为文本 text
d :delete 删除匹配到的行
p :print 显示匹配到的行,通常 p 会与参数 sed -n 搭配使用
w /file:write 保存模式空间中匹配到的行至指定的文件中
r /file :read 将指定文件的内容读取至当前模式空间中被匹配到的行后面,常用于实现文件合并
sed  -i '/Ethernet/r myfile' test  匹配Ethernet的行,读进来另一个文件的内容,读进来的文件的内容会插入到匹配Ethernet的行后  
s/pattern/replaces/:查找pattern用replaces替换,分隔符可自行指定,常用的分隔符有/, #, @等;
替换标记:
      g : 全局替换;
      w /file : 将替换的结果保存至指定文件中;sed -i 's/pattern/replaces/w my.txt'  test    将替换后的结果保存到my.txt中
      p : 显示替换成功的行;
      y : 用于(对应)转换字符;
      = : 打印行号;
      ! : 匹配后取反;
      l : 打印行号,并显示控制字符;
      q : 读取匹配到的行后退出;

应用

  • Demo Text
[root@localhost ~]# nl /etc/passwd | head -n5> demo.txt
[root@localhost ~]# cat demo.txt
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  • a \text(在指定行后新增)
# 在第 2 行后新增一行且不改变源文件
[root@localhost ~]# sed '2a CONSTANT DROPPING WEARS THE STONE!' demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
CONSTANT DROPPING WEARS THE STONE!
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

# 使用 \n 在第 2 行后新增多行且不改变源文件
[root@localhost ~]# sed '2a CONSTANT DROPPING WEARS THE STONE! \nCONSTANT DROPPING WEARS THE STONE!' demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
CONSTANT DROPPING WEARS THE STONE! 
CONSTANT DROPPING WEARS THE STONE!
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@localhost ~]# cat demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
   
# 使用 -i 选项,在第 2 后插入内容并改变源文件
[root@localhost ~]# sed -i '2a CONSTANT DROPPING WEARS THE STONE!' demo.txt 
[root@localhost ~]# cat demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
CONSTANT DROPPING WEARS THE STONE!
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  • i \text (在指定行前插入)
# 在第 3 行前插入一行且不改变源文件
[root@localhost ~]# sed '3i CONSTANT DROPPING WEARS THE STONE!' demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
CONSTANT DROPPING WEARS THE STONE!
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

# 使用 \n 插入多行且不改变源文件
[root@localhost ~]# sed '3i CONSTANT DROPPING WEARS THE STONE!\nCONSTANT DROPPING WEARS THE STONE' demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
CONSTANT DROPPING WEARS THE STONE!
CONSTANT DROPPING WEARS THE STONE
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@localhost ~]# cat demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    
# 使用 -i 选项,在第 4 行前插入一行且改变源文件
[root@localhost ~]# sed -i '4i CONSTANT DROPPING WEARS THE STONE!' demo.txt 
[root@localhost ~]# cat demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
CONSTANT DROPPING WEARS THE STONE!
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  • c \text 取代指定行的内容,同理,加 -i 选项会修改源文件
# 替换 2-5 行之间的内容
[root@localhost ~]# sed '2,5c  CONSTANT DROPPING WEARS THE STONE!' demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
CONSTANT DROPPING WEARS THE STONE!
  • d :delete 删除匹配到的行
# 删除第 3 行
[root@localhost ~]# sed '3d' demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
# 删除 第 2~4 行
[root@localhost ~]# sed '2,4d' demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

# 删除奇数行
[root@localhost ~]# sed '1~2d' demo.txt 
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin

# 删除包含第 2 行后两行
[root@localhost ~]# sed '2,+2d' demo.txt 
     1  root:x:0:0:root:/root:/bin/bash
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin


# 删除指定关键词(adm)行
[root@localhost ~]# sed '/adm/d' demo.txt
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  • p :print 显示匹配到的行,通常 p 会与参数 sed -n 搭配使用
[root@localhost ~]#  sed -n '/daemon/p' demo.txt
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
  • s/old/new/:查找 old 用 new 替换
# 将 root 替换为 User
[root@localhost ~]# sed 's/root/User/g' demo.txt
     1  User:x:0:0:User:/User:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

基础正则表达式字符

字符 意义
^word 搜寻的字串(word)在行首行
word$ 搜寻的字串(word)在行尾
. 匹配一个非换行符的字符,空格也算字符 如:/s.d/匹配s后接一个任意字符,然后是d
* 重复零个到无穷多个的前一个 RE 字符,* 之前必须要紧接着 一个 RE 字符
\ 将特殊符号的特殊意义去除
[list] 匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed
[^list] 匹配一个不在指定范围内的字符,反选
<word 匹配以 word 开始的行,如:/\<word/
word> 匹配以 word 结束的行,如/word\>/
x{m} 重复字符x,m次,如:/0{5}/匹配包含5个o的行
x{m,} 重复字符x,至少m次,如:/o{5,}/匹配至少有5个o的行
x{m,n} 重复字符x,至少m次,不多于n次,如:/o{5,10}/匹配5--10个o的行

元字符应用

  • Demo txt
[root@localhost ~]# ifconfig ens33
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.180.111.23  netmask 255.255.255.0  broadcast 10.180.111.255
        inet6 fe80::250:56ff:fe28:3506  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:28:35:06  txqueuelen 1000  (Ethernet)
        RX packets 63780  bytes 11329572 (10.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1789  bytes 132928 (129.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • ^word 匹配所有以 空格开头的前两行
[root@localhost ~]# ifconfig ens33 | sed -n '/^ /p'  | head -n 2
        inet 10.180.111.23  netmask 255.255.255.0  broadcast 10.180.111.255
        inet6 fe80::250:56ff:fe28:3506  prefixlen 64  scopeid 0x20<link>
  • word$ 匹配所有以 255 结尾的行
[root@localhost ~]# ifconfig ens33 | sed -n '/^ /p' | head -n 2 | sed -n '/255$/p'
        inet 10.180.111.23  netmask 255.255.255.0  broadcast 10.180.111.255
  • . 匹配一个非换行符的字符 如:/r.r/匹配 r 后接一个任意字符,然后是 r
[root@localhost ~]# ifconfig ens33 | sed -n '/r.r/p'
        RX errors 0  dropped 0  overruns 0  frame 0
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • [list] 匹配一个指定范围内的字符
[root@localhost ~]# ifconfig ens33 | sed -n '/[rt]s/p'
        RX packets 67344  bytes 11695515 (11.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1799  bytes 133756 (130.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • [^list] 匹配一个不在指定范围内的字符
[root@localhost ~]# ifconfig ens33 | sed -n '/inet[^6]/p'
        inet 10.180.111.23  netmask 255.255.255.0  broadcast 10.180.111.255

-/ \<word/ 匹配以 word 开始的行

[root@localhost ~]# ifconfig ens33 | sed -n '/\<ens33/p'
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

-/ word\>/ 匹配以 word 结束的行

[root@localhost ~]# ifconfig ens33 | sed -n '/255\>/p'
        inet 10.180.111.23  netmask 255.255.255.0  broadcast 10.180.111.255
  • x{m} 重复字符x,m次,如:/r{5}/ 匹配包含 2 个 r 的行
[root@localhost ~]# ifconfig ens33 | sed -n '/r\{2\}/p'
        RX errors 0  dropped 0  overruns 0  frame 0
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • x{m,} 重复字符x,至少m次,如:/1{2,}/ 匹配至少有2 个 1 的行
[root@localhost ~]# ifconfig ens33 | sed -n '/1\{2,\}/p'
        inet 10.180.111.23  netmask 255.255.255.0  broadcast 10.180.111.255
        RX packets 72499  bytes 12252286 (11.6 MiB)
  • 删除空白行
# sed 's/^\s*$/d' test.txt
# grep -v '^\s*$' test.txt
# awk NF test.txt
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容