文本三剑客之二---Sed用法
sed介绍
Stream EDitor, 行编辑器
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出或者-i进行修改。
功能
功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
参考:http://www.gnu.org/software/sed/manual/sed.html
使用sed
用法:
sed[option]... 'script' inputfile...
常用选项:
-n:不输出模式空间内容到屏幕,即不自动打印 -e:多点编辑 -f: /PATH/SCRIPT_FILE从指定文件中读取编辑脚本 -r:支持使用扩展正则表达式 -i:直接将处理的结果写入文件 -i.bak:备份文件并原处编辑
script:'地址命令'
地址定界:
(1) 不给地址:对全文进行处理
(2) 单地址:
- #: 指定的行,$:最后一行
- /pattern/:被此处模式所能够匹配到的每一行
(3) 地址范围:
- #,#
- #,+#
- /pat1/,/pat2/
- #,/pat1/
(4) ~:步进
- 1~2 奇数行
- 2~2 偶数行
编辑命令command
编辑命令:
d: 删除模式空间匹配的行,并立即启用下一轮循环 p: 打印当前模式空间内容,追加到默认输出之后 a: [\]text在指定行后面追加文本,支持使用\n实现多行追加 i: [\]text在行前面插入文本 c: [\]text替换行为单行或多行文本 w: /path/file保存模式匹配的行至指定文件 r: /path/file读取指定文件的文本至模式空间中匹配到的行后 =: 为模式空间中的行打印行号 !: 模式空间中匹配行取反处理
查找替换
s/// 查找替换,支持使用其它分隔符,s@@@,s###
替换标记:
g:行内全局替换
p:显示替换成功的行
w:/PATH/FILE将替换成功的行保存至文件中
sed用法演示
常用选项及地址定界配合演示
[root@centos7 ~]# sed -n '/^UUID/p' /etc/fstab # 筛选出UUID开头的行,其中-n是显示选中的行 UUID=64d9f83a-34c5-4025-94ff-504ca7a00a3f /boot xfs defaults 0 0 [root@centos7 ~]# sed -n '/^SELINUX=/cSELINUX=disabled' /etc/sysconfig/selinux # 将SELINUX=enforcing替换为SELINUX=disabled,-c的替换用法 SELINUX=disabled [root@centos7 ~]# sed '/^SELINUX=disabled/aSELINUX=enforcing' /etc/sysconfig/selinux # 在SELINUX=disabled追加SELINUX=enforcing,-a选项的追加用法 # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled SELINUX=enforcing
command编辑用法
[root@centos7 ~]# sed -n '/^root/,/^adm/p' /etc/passwd # 显示root到adm的行 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 [root@centos7 ~]# seq 10 | sed -n '1~2p' # 显示奇数行 1 3 5 7 9 [root@centos7 ~]# seq 10 | sed -n '2~2p' # 显示偶数行 2 4 6 8 10 [root@centos7 ~]# sed -n '/^UUID/!p' /etc/fstab # 不显示UUID开头的行 # # /etc/fstab # Created by anaconda on Sat Jan 4 16:31:31 2020 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/centos-root / xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0
查找替换用法:
[root@centos7 ~]# ifconfig eth0 | sed -nr 's/.*inet(.*)net.*/\1/p' # 使用分组的方式取出IP地址 192.168.7.100 [root@centos7 ~]# sed -n 's/UUID/uuid/gp' /etc/fstab # 将大写替换为小写 uuid=64d9f83a-34c5-4025-94ff-504ca7a00a3f /boot xfs defaults 0 0 [root@centos7 ~]# ifconfig eth0 | sed -r '2!d;s/.*inet (addr:)?//;s/ .*//' # 将centos6和centos7两个IP地址都取出来,其中2!d含义是将不是第二行的全删除,第一个s///是将匹配到的进行替换为空,第二个s///也是一样,将取出的数据替换为空,留下的就是IP地址。 192.168.7.100 [root@centos7 ~]# echo /etc/sysconfig/network-scripts/ | sed -nr 's@(.*/)([^/].*)/?@\1@p' # 其中(.*/)代表目录名部分 ([^/].*) 代表的是最后没有/的基名 /?代表最后的基名的/可有可无 /etc/sysconfig/ [root@centos7 ~]# echo /etc/sysconfig/network-scripts/ | sed -nr 's@(.*/)([^/].*)/?@\2@p' network-scripts/ [root@centos7 ~]# echo /etc/sysconfig/network-scripts | sed -nr 's@(.*/)([^/].*)/?@\2@p' network-scripts [root@centos7 ~]# sed -nr 's/[[:alpha:]]/\u&/gp' /etc/fstab # 将文件中的小写英文替换为大写,其中&是前面匹配到的内容。 # /ETC/FSTAB # CREATED BY ANACONDA ON SAT JAN 4 16:31:31 2020 # ACCESSIBLE FILESYSTEMS, BY REFERENCE, ARE MAINTAINED UNDER '/DEV/DISK' # SEE MAN PAGES FSTAB(5), FINDFS(8), MOUNT(8) AND/OR BLKID(8) FOR MORE INFO /DEV/MAPPER/CENTOS-ROOT / XFS DEFAULTS 0 0 UUID=64D9F83A-34C5-4025-94FF-504CA7A00A3F /BOOT XFS DEFAULTS 0 0 /DEV/MAPPER/CENTOS-SWAP SWAP SWAP DEFAULTS 0 0 [root@centos7 ~]# sed -nr 's/^[^#]/#&/gp' /etc/fstab # 将非#开头的行替换为#开头的行,g是全局替换,&是前面匹配到的内容 #/dev/mapper/centos-root / xfs defaults 0 0 #UUID=64d9f83a-34c5-4025-94ff-504ca7a00a3f /boot xfs defaults 0 0 #/dev/mapper/centos-swap swap swap defaults 0 0 [root@centos7 ~]# sed -nr 's@(GRUB_CMDLINE_LINUX.*)"@\1 net.ifnames=0"@p' /etc/default/grub # 将匹配到的文本行末添加一段ifnames=0 GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 rhgb quiet net.ifnames=0" [root@centos7 ~]# sed -rn 's/.* ([0-9]+)(\..*)/\1/p' /etc/centos-release # 查询当前linux版本号,适用于多种系统 7 ### 针对以下判断linux系统版本号,然后对对应的系统添加信息。 [root@centos7 ~]# num=$(sed -rn 's/(.*release )([0-9]+)(\..*)/\2/p' /etc/redhat-release) [root@centos7 ~]# [ $num -eq 7 ] && sed -nr 's/(.*CMD.*)"/\1 net.ifnames=0"/p' /etc/default/grub GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 rhgb quiet net.ifnames=0"
三种删除以#号开头的行或空行
[root@centos7 ~]# sed '/^#/d;/^$/d' /etc/default/grub # 第一种-d选项删除#开头或者空行 GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 rhgb quiet" GRUB_DISABLE_RECOVERY="true" [root@centos7 ~]# sed -e '/^#/d' -e '/^$/d' /etc/default/grub # 以-e选项进行删除 GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 rhgb quiet" GRUB_DISABLE_RECOVERY="true" [root@centos7 ~]# sed '/^#|^$/d' /etc/default/grub # 以|选项进行删除 GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 rhgb quiet" GRUB_DISABLE_RECOVERY="true"