1.释义
sed
对文本的处理很强大,并且sed
非常小,参数少,容易掌握,他的操作方式根awk
有点像。sed
按顺序逐行读取文件。然后,它执行为该行指定的所有操作,并在完成请求的修改之后的内容显示出来,也可以存放到文件中。完成了一行上的所有操作之后,它读取文件的下一行,然后重复该过程直到它完成该文件。在这里要注意一点,源文件(默认地)保持不被修改。sed
默认读取整个文件并对其中的每一行进行修改。说白了就是一行一行的操作。我用sed
主要就是用里面的替换功能,真的很强大。
2.系统帮助
用法: sed [选项]... {脚本(如果没有其他脚本)} [输入文件]... -n, --quiet, --silent 只匹配匹配的行,不匹配的删除,默认在不加-i参数时 不显示执行结果,如果要查看结果加p如:s/root/管理员/p -e 脚本, --expression=脚本 添加“脚本”到程序的运行列表,支持多个范围匹配 -f 脚本文件, --file=脚本文件 添加“脚本文件”到程序的运行列表 --follow-symlinks 直接修改文件时跟随软链接 -i[SUFFIX], --in-place[=SUFFIX] 使更改立即生效,如果没有-i参数将是查看结果(如果提供后缀,则进行备份) -c, --copy use copy instead of rename when shuffling files in -i mode -b, --binary does nothing; for compatibility with WIN32/CYGWIN/MSDOS/EMX ( open files in binary mode (CR+LFs are not treated specially)) -l N, --line-length=N 指定“l”命令的换行期望长度 --posix 关闭所有 GNU 扩展 -r, --regexp-extended 在脚本中使用扩展正则表达式 -s, --separate 将输入文件视为各个独立的文件而不是一个长的连续输入 -u, --unbuffered 从输入文件读取最少的数据,更频繁的刷新输出 -z, --null-data separate lines by NUL characters --help display this help and exit --version output version information and exit 如果没有 -e, --expression, -f 或 --file 选项,那么第一个非选项参数被视为 sed脚本。其他非选项参数被视为输入文件,如果没有输入文件,那么程序将从标准 输入读取数据。 GNU sed home page: <http://www.gnu.org/software/sed/>. General help using GNU software: <http://www.gnu.org/gethelp/>. E-mail bug reports to: <bug-sed@gnu.org>. Be sure to include the word ``sed'' somewhere in the ``Subject:'' field. 操作方式: s 替换匹配行中匹配的字符串 c 替换匹配行的整行内容 i 在匹配行的上面插入内容 a 在匹配行的下面插入内容 d 删除匹配的整行 p 打印匹配的行或指定行 n 从匹配行的下一行应用命令处理 ! 对匹配行以外的所有行应用命令处理 h 把模式空间里的内容重定向到暂存缓冲区 H 把模式空间里的内容追加到暂存缓冲区 g 取出暂存缓冲区的内容,将其复制到模式空间,覆盖该处原有的内容 G 取出暂存缓冲区的内容,将其复制到模式空间,追加在原有内容后面
3.查看
3.1.生成演示示例
[root@itbkz.com ~]#cat > test.txt <<EOF root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync EOF
3.2.第一行
[root@itbkz.com s]#sed -n '1p' test.txt root:x:0:0:root:/root:/bin/bash
3.3.最后一行
[root@itbkz.com s]#sed -n '$p' test.txt sync:x:5:0:sync:/sbin:/bin/sync
3.4.指定的多行
[root@itbkz.com s]#sed -n "1p;3p" test.txt root:x:0:0:root:/root:/bin/bash adm:x:3:4:adm:/var/adm:/sbin/nologin
3.5.指定的范围行
[root@itbkz.com s]#sed -n "1,3p" test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin
3.6.匹配行的行号
[root@itbkz.com s]#sed '/root/=' test.txt 1 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin 4 root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
将在匹配行的上面显示匹配行所在的行号。
3.7.反向打印
[root@itbkz.com s]#sed -nr '/^(#|$)/!p' /etc/fstab /dev/mapper/centos-root / xfs defaults 0 0 UUID=05a1f0df-3d9f-4432-afa3-5a5bd34c4f9f /boot xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0
4.替换
4.1.每行第一个匹配
[root@itbkz.com s]#sed 's/root/管理员/' test.txt [root@itbkz.com s]#cat test.txt 管理员:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin 管理员:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
将每一行中的第一个root替换成管理员,当一行中出现多个匹配结果,只替换第一个匹配
4.2.所有匹配
[root@itbkz.com s]#sed -i 's/root/管理员/g' test.txt [root@itbkz.com s]#cat test.txt 管理员:x:0:0:管理员:/管理员:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin 管理员:x:0:0:管理员:/管理员:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
将内容中所有的root替换成管理员,并立即写入到源文件
4.3.前备份在替换
[root@itbkz.com s]#sed -i.bak 's/root/管理员/g' test.txt [root@itbkz.com s]#cat test.txt test.txt.bak 管理员:x:0:0:管理员:/管理员:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin 管理员:x:0:0:管理员:/管理员:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
4.4.指定行范围替换
[root@itbkz.com s]#sed '1,4s/bin/itbkz/g' test.txt root:x:0:0:root:/root:/itbkz/bash itbkz:x:1:1:itbkz:/itbkz:/sitbkz/nologin adm:x:3:4:adm:/var/adm:/sitbkz/nologin root:x:0:0:root:/root:/itbkz/bash sync:x:5:0:sync:/sbin:/bin/sync
将1-4行中所有的bin替换为itbkz
4.5.指定行范围多次替换
方法1: [root@itbkz.com s]#sed '1,3s/root/管理员/g;4,5s/root/admin/g' test.txt 管理员:x:0:0:管理员:/管理员:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin admin:x:0:0:admin:/admin:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync 方法2: [root@itbkz.com s]#sed -e '1,3s/root/管理员/g' -e '4,5s/root/admin/g' test.txt 管理员:x:0:0:管理员:/管理员:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin admin:x:0:0:admin:/admin:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
将1-3行中所有的root替换成管理员,在将4-5行中所有的root替换成admin
4.6.替换以什么开头的行
[root@itbkz.com s]#sed 's/^adm/管理员/' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin 管理员:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
将行中以adm开头的内容替换成管理员(加了
^
符号,所以后面加g
也是只替换首部出现的adm)4.7.转义替换
[root@itbkz.com s]#sed 's/\/root/管理员/g' test.txt root:x:0:0:root:管理员:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:管理员:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
将所有行中的/root替换为管理员,要使用转义符,也可以直接使用
#
字符来替换,这样不需要转义符,如将上面的替换为's#/root#管理员#g'
即可4.8.匹配行到匹配行替换
[root@itbkz.com s]#sed '/^bin/,/root/s/bin/管理员/g' test.txt root:x:0:0:root:/root:/bin/bash 管理员:x:1:1:管理员:/管理员:/s管理员/nologin adm:x:3:4:adm:/var/adm:/s管理员/nologin root:x:0:0:root:/root:/管理员/bash sync:x:5:0:sync:/sbin:/bin/sync
从行首开头是bin的匹配行开始到有root的行结束,然后将范围内的所有bin替换为管理员(这里面结束范围以行为单位,而不是匹配的第一个项或是第几个项结束),将里面所有的bin替换成管理员
4.9.匹配行下行开始替换
[root@itbkz.com s]#sed '/adm/{n;s/root/管理员/g}' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin 管理员:x:0:0:管理员:/管理员:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
找到匹配adm的行,然后将它下面的一行的所有root替换为管理员,如果替换行的下一行还有匹配的内容将不会替换,只会替换匹配行下一行的所有匹配内容
4.10.匹配内容转为大写
[root@itbkz.com s]#sed '1,3y/root/ROOT/' test.txt ROOT:x:0:0:ROOT:/ROOT:/bin/bash bin:x:1:1:bin:/bin:/sbin/nOlOgin adm:x:3:4:adm:/vaR/adm:/sbin/nOlOgin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
y
的作用是将匹配的字符换成大写,不过替换字符和被替换字符长度要一样4.11.匹配行替换
[root@itbkz.com s]#sed -e '/root/h' -e '/adm/g' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin root:x:0:0:root:/root:/bin/bash root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
用匹配root的行来替换匹配adm的行
4.12.指定行整行替换
[root@itbkz.com s]#sed '4c root' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root sync:x:5:0:sync:/sbin:/bin/sync
4.13.匹配行整行替换
[root@itbkz.com s]#sed '/root/c 管理员' test.txt 管理员 bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin 管理员 sync:x:5:0:sync:/sbin:/bin/sync
4.14.替换到指定行退出
[root@itbkz.com s]#sed 's/bin/管理员/g;3q' test.txt root:x:0:0:root:/root:/管理员/bash 管理员:x:1:1:管理员:/管理员:/s管理员/nologin adm:x:3:4:adm:/var/adm:/s管理员/nologin
从第一行开始将bin替换成管理员,当到达第3行的时候退出,
3q
的意思是到第3行的时候退出,后面的行将会被删除4.15.指定范围行注释
[root@itbkz.com s]#sed '3,5s/^/#/' test.txt 管理员:x:0:0:管理员:/管理员:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin #adm:x:3:4:adm:/var/adm:/sbin/nologin #管理员:x:0:0:管理员:/管理员:/bin/bash #sync:x:5:0:sync:/sbin:/bin/sync
4.16.取消指定范围行注释
[root@itbkz.com s]#sed '3,5s/^#//' test.txt 管理员:x:0:0:管理员:/管理员:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin 管理员:x:0:0:管理员:/管理员:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
4.17.匹配字符串行注释
[root@template yum.repos.d]#sed '/mirrors.cloud.aliyuncs.com/s/^/#/' /etc/yum.repos.d/Centos-7.repo [base] name=CentOS-$releasever - Base - mirrors.aliyun.com failovermethod=priority baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/ http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/ # http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/ gpgcheck=1 gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
匹配字符串行及下一行注释
sed '/mirrors.aliyuncs.com/,+1 s/^/#/' /etc/yum.repos.d/Centos-7.repo
,+1
表示匹配字符串行和下一行,一共2
行注释,如果有多行匹配字符串将全部替换。去掉匹配字符串行的注释sed '/mirrors.aliyuncs.com/s/^#//' /etc/yum.repos.d/Centos-7.repo
4.18.引用替换增加内容
[root@itbkz.com s]#sed 's#root#&管理员#g' test.txt root管理员:x:0:0:root管理员:/root管理员:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root管理员:x:0:0:root管理员:/root管理员:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
&
符号引用前面匹配的内容5.删除
5.1.删除有匹配字符串的行
[root@itbkz.com s]#sed /root/d test.txt bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync
删除所有行中有root的整行
5.2.改变删除匹配行结果
[root@itbkz.com s]#sed -i /root/d test.txt [root@itbkz.com s]#cat test.txt bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync
将带root的行删除并写到文件中生效,使用
-i
参数立即将结果写入到文件,这时原文件内容才会被改变5.3.删除指定的多行
方法1: [root@itbkz.com s]#sed '2d;4d' test.txt root:x:0:0:root:/root:/bin/bash adm:x:3:4:adm:/var/adm:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync 方法2: [root@itbkz.com s]#sed -e '2d' -e '4d' test.txt root:x:0:0:root:/root:/bin/bash adm:x:3:4:adm:/var/adm:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync
5.4.删除不匹配的行并替换
[root@itbkz.com s]#sed -n 's/root/管理员/p' test.txt 管理员:x:0:0:root:/root:/bin/bash 管理员:x:0:0:root:/root:/bin/bash
删除不匹配的行,在将匹配行中的root替换成管理员并打印在屏幕上。替换将只替换每一行中第一个匹配的内容,如果一行中出现多个匹配,将只替换第一个,其它没有任何一次匹配的行将会被全部删除。如果增加
-i
参数将会立即改变文件内容跟打印结果一样,如果不加p
,将不会打印,如果增加g
,将会替换所有行中所有匹配的内容5.5.删除指定范围行
[root@itbkz.com s]#sed '1,3d' test.txt root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
删除1-3行
5.6.删除指定行后所有行
[root@itbkz.com s]#sed '3,$d' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin
删除第3行以后的行,包括第3行也会被删除,把
$
当成最大行数就行了5.7.删除以什么结尾的行
[root@itbkz.com s]#sed '/\(nologin\|bash\)$/d' test.txt sync:x:5:0:sync:/sbin:/bin/sync
删除以nologin和bash结尾的行
5.8.删除匹配行中间的行
[root@itbkz.com s]#sed '/root/,/^root/d' test.txt sync:x:5:0:sync:/sbin:/bin/sync
从root行开始到开头是root的行删除
5.9.删除特殊空行
[root@itbkz.com s]#sed '/^$/d;/^ /d;/\t/d' test.txt
以上方法将删除内容为空行(
^$
)、空格行(^
)、制表符行(\t
)6.读入文件
6.1.匹配行下读入内容
[root@itbkz.com s]#sed '/^root/r /etc/hosts' test.txt root:x:0:0:root:/root:/bin/bash 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 sync:x:5:0:sync:/sbin:/bin/sync
在所有开头是root的行下面读入/etc/hosts文件的内容
7.写出文件
7.1.匹配数字行写到文件
[root@itbkz.com s]#sed '/[[:digit:]]/w xin.txt' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin abcdefg root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync abcdefg [root@itbkz.com s]#cat xin.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
将所有行中包括数字的行的内容写入到xin.txt文件
8.增加
8.1.每行前/行尾添加字符
[root@docker tmp]#sed 's/^/增加内容 /g' test.txt 增加内容 root:x:0:0:root:/root:/bin/bash 增加内容 bin:x:1:1:bin:/bin:/sbin/nologin 增加内容 adm:x:3:4:adm:/var/adm:/sbin/nologin 增加内容 root:x:0:0:root:/root:/bin/bash 增加内容 sync:x:5:0:sync:/sbin:/bin/sync
每行后增加字符只需要将
^
符号替换成$
符号即可,^
代表头部,$
代表尾部8.2.将匹配行插入到行尾
[root@itbkz.com s]#sed -e '/adm/h' -e '$G' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync adm:x:3:4:adm:/var/adm:/sbin/nologin
将匹配adm行的整行内容插入到最后一行的下面,
h
的作用是将找到的行放到一个缓存区,G
的作用是将缓存区中的内容放到最后一行8.3.匹配行尾加字符
[root@itbkz.com s]#sed 's/bash/&\/管理员/g' test.txt root:x:0:0:root:/root:/bin/bash/管理员 bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash/管理员 sync:x:5:0:sync:/sbin:/bin/sync
将所有行中以bash结尾的行后面增加/管理员
8.4.匹配行下面插入内容
[root@itbkz.com s]#sed '/root/a盛行' test.txt root:x:0:0:root:/root:/bin/bash 盛行 bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash 盛行 sync:x:5:0:sync:/sbin:/bin/sync
将所有匹配root的行的下面插入盛行字符串,如果想添加多行可以使用
\n
来换行,如果需要在盛行
前面增加空格,可以使用sed '/root/a\ 盛行'
8.5.指定行下面插入内容
[root@itbkz.com s]#sed '1a 盛行' test.txt root:x:0:0:root:/root:/bin/bash 盛行 bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
8.6.匹配行上面插入内容
[root@itbkz.com s]#sed '/^adm/i\\盛行' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin 盛行 adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
将所有开头是root的行的上面插入盛行字符串
8.7.指定行上面插入内容
[root@itbkz.com s]#sed '1i 盛行' test.txt 盛行 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync
8.8.尾行增加多行内容
[root@itbkz.com s]#sed '$a itbkz.com\nIT博客站' test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync itbkz.com IT博客站
9.扩展
9.1.取父目录路径
方法1: [root@itbkz.com s]#echo "/etc/sysconfig/network-scripts/ifcfg-ens192" |sed 's@\(/.*/\)[^/]\{1,\}/\?@\1@' /etc/sysconfig/network-scripts/ 方法2: [root@itbkz.com s]#echo "/etc/sysconfig/network-scripts/ifcfg-ens192" | sed -r 's@(/.*/)[^/]+/?@\1@' /etc/sysconfig/network-scripts/
取出/etc/sysconfig/network-scripts/ifcfg-ens192路径的父目录路径。取得一个文件(或目录)路径的父目录路径,
s@@@
为替换格式,\(/.*/\)
是指一个/
后面跟了任意字符又跟了一个/
,其中\(\)
是用来把匹配内容作为一个整体后向引用,[^/]\{1,\}
是指一个非/
字符出现了一次,两次,或多次/\?
是指/
出现了0次或1次,\1
是后向引用前面匹配的内容9.2.取IP地址
[root@itbkz.com s]#ifconfig ens192 | sed -nr 's#.*et (.*) netmask (.*)#\1#p' 192.168.1.246
10.正则表达式
关于常用正则表达式参考以下文章:
正则表达式(grep|sed|awk)基础正则表达式BRE与扩展的正则表达式ERE
文章目录[隐藏] 1基础正则(BRE)2扩展正则(ERE)3特殊匹配列表 1.基础正则(BRE) .:匹配单个 […]