当前位置 知且行 linux 实例详解sed命令行 下一篇:

实例详解sed命令行

sed是一种流编辑器,以行为单位进行文本处理,可以将数据行进行替换、删除、新增、选取等操作。

sed 一次从文件中读一行,并且将这一行放到sed的工作车间(pattern space),在工作车间处理完毕后,将结果输出到标准输出,其间并不会动原文件的内容

语法如下:

sed [options] 'command' file(s)

接下来以诗仙李白写给杨贵妃的清平调为素材

$ cat 清平调.txt
其一
云想衣裳花想容,春风拂槛露华浓
若非群玉山头见,会向瑶台月下逢
其二
一枝红艳露凝香,云雨巫山枉断肠
借问汉宫谁得似,可怜飞燕倚新妆
其三
名花倾国两相欢,长得君王带笑看
解释春风无限恨,沉香亭北倚阑干

匹配内容

p匹配内容有个很有意思,会将匹配到的数据输出两遍,未匹配的行输出一遍,这个设定基本没卵用,因此要加上-n参数,就能屏蔽到未匹配到的行数

  • 输出前三行数据
$ sed '1,3p' 清平调.txt # 结果是匹配到的前三行数据会输出两遍,未匹配到的会输出一遍
$ sed -n '1,3p' 清平调.txt # 只输出匹配到的前三行数据,符合我们的预期
其一
云想衣裳花想容,春风拂槛露华浓
若非群玉山头见,会向瑶台月下逢
  • 输出以开头的行
$ sed -n '/^其/p' 清平调.txt
其一
其二
其三

行定位

  • 定位一行
$ sed -n '5p' 清平调.txt
一枝红艳露凝香,云雨巫山枉断肠

$ nl 清平调.txt | sed -n '5p'
     5	一枝红艳露凝香,云雨巫山枉断肠
  • 定位多行
$ nl 清平调.txt | sed -n '4,6p' # 指定行数
     4	其二
     5	一枝红艳露凝香,云雨巫山枉断肠
     6	借问汉宫谁得似,可怜飞燕倚新妆

$ nl 清平调.txt | sed -n '/其一/,/其二/p' # 指定内容,匹配从其一至其二的行
     1	其一
     2	云想衣裳花想容,春风拂槛露华浓
     3	若非群玉山头见,会向瑶台月下逢
     4	其二
  • 反向匹配
$ nl 清平调.txt | sed -n '1,6!p' # 匹配除了第1至6行之外的行
     7	其三
     8	名花倾国两相欢,长得君王带笑看
     9	解释春风无限恨,沉香亭北倚阑干
  • 间隔行
$ nl 清平调.txt | sed -n '1~2p' # 从第1行开始,步长为2,即打印所有奇数行
     1	其一
     3	若非群玉山头见,会向瑶台月下逢
     5	一枝红艳露凝香,云雨巫山枉断肠
     7	其三
     9	解释春风无限恨,沉香亭北倚阑干

新增行

$ nl 清平调.txt | sed '3a==============' # 在第3行后面新增数据
     1	其一
     2	云想衣裳花想容,春风拂槛露华浓
     3	若非群玉山头见,会向瑶台月下逢
==============
     4	其二
     5	一枝红艳露凝香,云雨巫山枉断肠
     6	借问汉宫谁得似,可怜飞燕倚新妆
     7	其三
     8	名花倾国两相欢,长得君王带笑看
     9	解释春风无限恨,沉香亭北倚阑干
$ nl 清平调.txt | sed '1,5a==============' # 在第1至5行,每行后面都新增内容
     1	其一
==============
     2	云想衣裳花想容,春风拂槛露华浓
==============
     3	若非群玉山头见,会向瑶台月下逢
==============
     4	其二
==============
     5	一枝红艳露凝香,云雨巫山枉断肠
==============
     6	借问汉宫谁得似,可怜飞燕倚新妆
     7	其三
     8	名花倾国两相欢,长得君王带笑看
     9	解释春风无限恨,沉香亭北倚阑干

插入行

$ nl 清平调.txt | sed '1,3i==============' # 在1至3每行前面增加内容
==============
     1	其一
==============
     2	云想衣裳花想容,春风拂槛露华浓
==============
     3	若非群玉山头见,会向瑶台月下逢
     4	其二
     5	一枝红艳露凝香,云雨巫山枉断肠
     6	借问汉宫谁得似,可怜飞燕倚新妆
     7	其三
     8	名花倾国两相欢,长得君王带笑看
     9	解释春风无限恨,沉香亭北倚阑干

替代行

$ nl 清平调.txt | sed '1,7c==============' # 替换1-7行内容
==============
     8	名花倾国两相欢,长得君王带笑看
     9	解释春风无限恨,沉香亭北倚阑干

替换是整体替换,而不是每一行替换

删除行

$ nl 清平调.txt | sed '1,7d' # 删除1至7行内容
     8	名花倾国两相欢,长得君王带笑看
     9	解释春风无限恨,沉香亭北倚阑干

删除空行

$ sed '/^$/d' 清平调.txt # 正则^$表示空行

在文件末尾追加内容

$ sed '$a 全诗构思精巧,辞藻艳丽\n描绘出人花交映、迷离恍惚的景象' 清平调.txt
其一
云想衣裳花想容,春风拂槛露华浓
若非群玉山头见,会向瑶台月下逢
其二
一枝红艳露凝香,云雨巫山枉断肠
借问汉宫谁得似,可怜飞燕倚新妆
其三
名花倾国两相欢,长得君王带笑看
解释春风无限恨,沉香亭北倚阑干
全诗构思精巧,辞藻艳丽
描绘出人花交映、迷离恍惚的景象

替换

$ sed 's/其/第/gi' 清平调.txt # g表示全局替换,如果没有g,只替换每行匹配到的第一个内容,i表示忽略大小写
第一
云想衣裳花想容,春风拂槛露华浓
若非群玉山头见,会向瑶台月下逢
第二
一枝红艳露凝香,云雨巫山枉断肠
借问汉宫谁得似,可怜飞燕倚新妆
第三
名花倾国两相欢,长得君王带笑看
解释春风无限恨,沉香亭北倚阑干

执行多个sed指令

$ nl 清平调.txt | sed -n -e '2,3p' -e '5,6p' # 获取不连续行
     2	云想衣裳花想容,春风拂槛露华浓
     3	若非群玉山头见,会向瑶台月下逢
     5	一枝红艳露凝香,云雨巫山枉断肠
     6	借问汉宫谁得似,可怜飞燕倚新妆

写入空行

$ sed 'G' 清平调.txt # 在每行之后新增一行
其一

云想衣裳花想容,春风拂槛露华浓

若非群玉山头见,会向瑶台月下逢

其二

一枝红艳露凝香,云雨巫山枉断肠

借问汉宫谁得似,可怜飞燕倚新妆

其三

名花倾国两相欢,长得君王带笑看

解释春风无限恨,沉香亭北倚阑干
$ sed 'G;G' 清平调.txt # 在每行之后新增两行

修改原文件

  • 直接修改原文件
$ sed -i 's/其/第/g' 清平调.txt
  • 拷贝原文件副本再进行修改
$ sed -i.bak 's/第/其/g' 清平调.txt # 先将内容复制一份 推荐如此使用,安全
$ ls | grep 清平调
清平调.txt
清平调.txt.bak

小括号反向引用

$ sed 's/\(其\)/\1中第/g' 清平调.txt
其中第一
云想衣裳花想容,春风拂槛露华浓
若非群玉山头见,会向瑶台月下逢
其中第二
一枝红艳露凝香,云雨巫山枉断肠
借问汉宫谁得似,可怜飞燕倚新妆
其中第三
名花倾国两相欢,长得君王带笑看
解释春风无限恨,沉香亭北倚阑干

仅当符合某条件时才进行内容替换

$ sed '/一/s/其/第/g' 清平调.txt # 当行中同时出现 一 与 其 时,才将 其 替换成 第
第一
云想衣裳花想容,春风拂槛露华浓
若非群玉山头见,会向瑶台月下逢
其二
一枝红艳露凝香,云雨巫山枉断肠
借问汉宫谁得似,可怜飞燕倚新妆
其三
名花倾国两相欢,长得君王带笑看
解释春风无限恨,沉香亭北倚阑干

批量替换

$ sed 's/其/第/g;s/一/1/g;s/二/2/g;s/三/3/g' 清平调.txt
第1
云想衣裳花想容,春风拂槛露华浓
若非群玉山头见,会向瑶台月下逢
第2
1枝红艳露凝香,云雨巫山枉断肠
借问汉宫谁得似,可怜飞燕倚新妆
第3
名花倾国两相欢,长得君王带笑看
解释春风无限恨,沉香亭北倚阑干

执行多个sed命令

-{}: 用;分开多个sed命令

nl /etc/passwd | sed '{20,30d;s/false/true/}' # 删除第20至30行,将false替换成true

读取一个输入 行

$ nl passwd | sed -n '{n;p}'  # 间隔了一行取出 偶数行
$ nl passwd | sed -n '{p;n}' # 奇数行输出

# 另一种实现方式
$ nl passwd | sed '1~2p'
$ nl passwd | sed '2~2p'
$ nl passwd | sed -n '{n;n;p}'
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     6  sync:x:5:0:sync:/sbin:/bin/sync
     9  mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

$ nl passwd | sed -n '{n;p;n}'
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     5  lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     8  halt:x:7:0:halt:/sbin:/sbin/halt

替换固定字符串

$ sed 's/^[a-z_-]\+/& /' /etc/passwd # 用户名后加上空格
$ sed 's/^[a-z_-]\+/\U&/' /etc/passwd # 将用户名替换成大写

数据筛选

$ sed 's/\(^[a-z0-9_-]\+\):x:\([0-9]\+\):\([0-9]\+\):.*$/user:\1 uid:\
2 gid:\3/' /etc/passwd
user:root uid:0 gid:0
user:daemon uid:1 gid:1
user:bin uid:2 gid:2
...

复制指定文件插入到匹配行

$ echo -e '2412424124\n3432534\n5353523523' > 123.txt
$ echo -e 'dfgetetetete\njpkpwefwe\nlidwoew' > abc.txt
$ sed '1r 123.txt' abc.txt  # 将123.txt插入到abc.txt的第1行后面
dfgetetetete
2412424124
3432534
5353523523
jpkpwefwe
lidwoew

读文件并不改变两个文件的内容,只是输出,需要用重定向将结果保存

提前退出

$ nl /etc/passwd | sed '3q'  # 只取出前3行
     1  root:x:0:0:root:/root:/bin/zsh
     2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
     3  bin:x:2:2:bin:/bin:/usr/sbin/nologin
$ nl /etc/passwd | sed '/nologin/q' # 找到第一个nologin就退出
     1  root:x:0:0:root:/root:/bin/zsh
     2  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

与find结合使用

find ./ -type f -exec sed -i -e 's/charset=gbk/charset=utf-8/g' {} \;  # 将find检索结果文件进行替换
转载必须注明出处:https://www.zhiqiexing.com/120.html

关于我

我希望能成为一个认真、有趣、创造更多价值的人
关注微信
微信扫一扫关注我

微信扫一扫关注我

返回顶部