指点成金-最美分享吧

登录

shell法宝之sed,修改文件内容的好帮手

佚名 举报

篇首语:本文由小编为大家整理,主要介绍了shell法宝之sed,修改文件内容的好帮手相关的知识,希望对你有一定的参考价值。

sed编辑器

  • 一、概述
    • 1.1 工作流程
    • 1.2 命令格式
  • 二、常用选项
  • 三、常用操作
  • 四、命令代码的使用
    • 4.1 打印内容
    • 4.2 寻址方式
      • 部分简易命令
      • 系统文件内过滤需求
    • 4.3 删除方式
    • 4.4 替换
      • 格式
      • 替换标记
      • 模板
    • 4.5 插入

一、概述

  • sed是一种流编辑器,会在编辑数据之前基于预先提供的一组规则来编辑数据流
  • sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本中

1.1 工作流程

读取、执行、显示

  • 读取:sed从输入流(文件、管道、标准输入)中提取一行内容存储到临时的缓冲区
  • 执行:默认情况下,所有的sed命令都在缓冲区内执行,除非指定行的地址,否则sed将会在所有行上依次执行
  • 显示:发送修改后的内容到输出流,发送数据后,缓冲区清空,所有的文件内容处理完之前,上述过程将会一直重复执行,直到内容被处理完

默认情况下所有的命令都是在缓冲区完成,所有输入的文件本身不会发生变化,除非我们手动进行重定向存储

1.2 命令格式

  • 第一种
sed -e "操作" 文件1 文件2 ...sed -n -e "操作" 文件1 文件2 ...sed -f 脚本文件 文件1 文件2sed -i -e "操作" 文件1 文件2 ...
  • 第二种
sed -e "n{操作1操作2...}" 文件1 文件2 ...

二、常用选项

选项解释
-e 或 - -expression=表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用
-f 或 - -file=用指定的脚本文件来处理输入的文本文件
-h 或 - -help显示帮助
-n、- -quiet 或 silent禁止 sed 编辑器输出,但是可以与 p 命令一起使用完成输出
-i直接修改目标文本文件

三、常用操作

选项解释
s替换、替换指定字符
d删除、删除选定的行
a增加、在当前行下面增加一行指定内容
i插入、在选定行上面插入一行指定内容
c替换、将选定行替换为指定的内容
y字符转换、转换前后的字符长度必须相同
p打印、如果同时指定行,表示打印行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以 ASCII 码输出。通常与 “ -n ” 一起使用
=打印行号
l(小写L)打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符 \t )

四、命令代码的使用

4.1 打印内容

sed "p" cc.sed# 打印文件内容

sed -ne "p" cc.sed# 打印内容

sed -ne "=" cc.sed# -n显示行号,不显示内容

sed -ne "l" cc.sed# 打印文本,包括不可打印的字符$

4.2 寻址方式

两种

  • 以数字形式来表示区间
  • 用文本模式来过滤出行

部分简易命令

以 “ cc.sed ” 文本为模板,按照以下命令完成需求

sed -n "1p" cc.sed # 打印第一行内容1sed -n "5p" cc.sed # 打印第五行内容5sed -n "$p" cc.sed # 打印最后一行,$代表最后0sed -n "2,5p" cc.sed # 打印2至5行的内容2345sed -n "2,+5p" cc.sed # 打印第二行开始,往后数五行2345sed -n "8,$p" cc.sed # 打印第八行到最后67890sed -n "p;n" cc.sed # 打印奇数行13579sed -n "n;p" cc.sed # 打印偶数行24680sed -n "5,${n;p}" cc.sed # 从第五行开始,打印偶数行至最后680

系统文件内过滤需求

  • 过滤passwd文件内有root信息的
sed -n "/root/p" /etc/passwd# 搜索带有root信息root:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologin
  • 过滤 “ a ” 开头的行
sed -n "/^a/p" /etc/passwd# 以a开头的行adm:x:3:4:adm:/var/adm:/sbin/nologinabrt:x:173:173::/etc/abrt:/sbin/nologinavahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologinapache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
  • 过滤 “ nologin ” 结尾的行,$表示结尾
sed -n "/nologin$/p" /etc/passwd# 过滤noligin结尾的行,内容较多,筛选部分bin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  • 查找 “ ftp ” 和 “ root ” 的相关行
第一种:sed -n "/ftp\|root/p" /etc/passwd# | 表示或,需要用反斜杠 \ 来注释,否则无法检索root:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologin第二种:sed -nr "/ftp|root/p" /etc/passwd# 使用-r命令可以不需要添加反斜杠root:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
  • 从搜索固定行数至内容的命令
sed -n "2,/sync/{=;p}" /etc/passwd# 从第二行打印到包含sync的则一行,配合-n可以看行号2bin:x:1:1:bin:/bin:/sbin/nologin3daemon:x:2:2:daemon:/sbin:/sbin/nologin4adm:x:3:4:adm:/var/adm:/sbin/nologin5lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin6sync:x:5:0:sync:/sbin:/bin/sync
  • 根据检索条件匹配出内容,-r表示支持扩展正则表达式
[root@ccc lianxi]# sed -nr "/ro{1,}t/p" /etc/passwd# 匹配一位及以上o,得出结果rot和root都可以出来root:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologin

4.3 删除方式

简单的几个命令

sed "d" cc.sed # 删除所有内容sed "5d" cc.sed # 删除第五行123467890sed "2,8d" cc.sed # 删除2到8行17890sed "$d" cc.sed # 删除最后一行123456789[root@ccc lianxi]# # 删除空行1234567890

对系统文件做更改

  • 删除passwd文件内 nologin 结尾的行
sed "/nologin$/d" /etc/passwd# nologin结尾,$代表结尾root:x:0:0:root:/root:/bin/bashsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltdcc:x:1000:1000:dcc:/home/dcc:/bin/bash
  • 除了 nologin ,其他都删除
sed "/nologin$/!d" /etc/passwd# 只留下结尾 nologin 的行bin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinmail:x:8:12:mail:/var/spool/mail:/sbin/nologinoperator:x:11:0:operator:/root:/sbin/nologingames:x:12:100:games:/usr/games:/sbin/nologinftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
  • 从1开始删除,一直删除到4结束,不区分字符数量
    模板

  • sed "/1/,/4/d’ cc.sed

  • 删除从1开头的到4开头的行,和前面的删除1到4行有区别

4.4 替换

格式

行范围 s/旧字符串/新字符串/替换标记

替换标记

  • 数字:表示新字符串将要替换到第几处所匹配的地方
  • g:表面新字符串将要替换所有匹配的地方
  • p:打印与替换命令相匹配的行,与 “ -n ” 共同使用
  • w 文件:将替换的结果写到指定的文件中

模板

  • 替换passwd文件内的 root 为 AAAAA
  • 不加数字默认只会替换匹配到的第一个内容
  • 按行匹配
sed -n "s/root/AAAAA/p" /etc/passwd# 替换root为AAAAAAAAAA:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/AAAAA:/sbin/nologinsed -n "s/root/AAAAA/2p" /etc/passwd# 加了数字2,只有一条符合条件(第二位root被替换)root:x:0:0:AAAAA:/root:/bin/bash
  • 匹配到的 root 全都替换 AAAAA
sed -n "s/root/AAAAA/gp" /etc/passwd# g代表全部替换AAAAA:x:0:0:AAAAA:/AAAAA:/bin/bashoperator:x:11:0:operator:/AAAAA:/sbin/nologin
  • 给行的开头添加 “ # ”
sed "1,5 s/^/#/" cc.sed # ^代表行首,1,5表示选中第1至5行#1#2#3#4#5678
  • 给指定1开的行末尾加上 “ # ”
sed "/^1/ s/$/#/" cc.sed # ^代表开头,在匹配行的末尾加上#1#23456789011#22
  • 将passwd文件内的第1-15行写入到新的文件中,并在开头加上#
sed "1,15 s/^/#/w ceshi.txt" /etc/passwdcat ceshi.txt #root:x:0:0:root:/root:/bin/bash#bin:x:1:1:bin:/bin:/sbin/nologin#daemon:x:2:2:daemon:/sbin:/sbin/nologin#adm:x:3:4:adm:/var/adm:/sbin/nologin#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#operator:x:11:0:operator:/root:/sbin/nologin#games:x:12:100:games:/usr/games:/sbin/nologin#ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin#nobody:x:99:99:Nobody:/:/sbin/nologin#systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin#dbus:x:81:81:System message bus:/:/sbin/nologin
  • 替换passwd文件内 bin/bash 为 bin/csh
  • !号为字符串的分隔符
sed -n "s!/bin/bash!/bin/csh!p" /etc/passwd# !/bin/bash!为原有字符 /bin/csh!为新字符,用!号分隔开root:x:0:0:root:/root:/bin/cshdcc:x:1000:1000:dcc:/home/dcc:/bin/csh123456:x:1001:1001::/home/123456:/bin/cshccd:x:1002:1002::/home/ccd:/bin/cshddccdd:x:1003:1003::/home/ddccdd:/bin/cshdccccccc:x:1004:1004::/home/dccccccc:/bin/cshccccc:x:1005:1005::/home/ccccc:/bin/cshccaa:x:1006:1006::/home/ccaa:/bin/cshccaacc:x:1007:1007::/home/ccaacc:/bin/cshdcc666:x:1008:1008::/home/dcc666:/bin/cshccaz:x:1009:1009::/home/ccaz:/bin/csh
  • 将文本内74577更换为7676
sed -i "s7\745\7\77\76\767g" cc.sed# s后面的7为分隔符,并不是我们认知的7,需要用\来转义,后面出现的7同样需要,否则会和替换符重叠cat cc.sed 1235267676

4.5 插入

  • 将文件内第三行内容替换为 ABC
sed "/3/c ABC" cc.sed # 3表示第三行, c为替换12ABC5267676
  • 替换文件内7676为ABCD
[root@ccc lianxi]# sed "/7676/ y/7676/ABCD/" cc.sed # 选定7676 替换,必须同样位数替换123526ABAB
  • 在文件内1到3行的下方插入ABCD
sed "1,3a ABCD" cc.sed # a为文件下方增加一行内容,i为文件上方增加1ABCD2ABCD3ABCD5
  • 将文件内第三行内容剪切到末尾
sed "/3/{H;d};$G" cc.sed# H表示复制,G表示粘贴,因为需求是剪切,所以需要用 d 删除原有的内容1252676763
  • 123ABC 对调为 CBA321
  • 方法比较古板
echo "123ABC" | sed -r "s/(1)(2)(3)(A)(B)(C)/\6\5\4\3\2\1/"CBA321

以上是关于shell法宝之sed,修改文件内容的好帮手的主要内容,如果未能解决你的问题,请参考以下文章