文本处理sed
简介:
行编辑器,自动逐行去处理目标文件中的行,具有自动打印功能
功能:
主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
语法:
sed [OPTION]... 'script' FILENAME...
常用选项:
-n:取消自动打印
-e:多点编辑
-f<script文件>或--file=<script文件>:以选项中指定的script文件来处理输入的文本文件
-r:支持使用扩展正则表达式
-i.bak:备份文件并原处编辑
例:sed -i.bak 'script' FILENAME #备份要更改的目标文件
script:
'地址命令'
#地址:文件中的行
#命令:sed中的一些命令
地址:
(1) 不给地址:对文件中的所有行进行处理
(2) 单地址:
#:处理指定的行号
例:sed -n '2p' /etc/passwd #打印/etc/passwd文件中的第二行,"-n"选项关闭sed自动打印
$:处理最后一行
例:sed -n '$p' /etc/passwd #打印/etc/passwd文件中的最后一行
/模式/:可写正则表达式,匹配的模式
例:sed -n '/^UUID/p' /etc/fstan #打印/etc/fstab文件中^UUID开头的行
(3) 地址范围:
#,# :处理从第几行到第几行之间的行
例:sed -n '8,12p' /etc/passwd #打印/etc/passwd文件中第8行到第12行的所有行
#,+#:第几行到这行之后的多少航
例:sed -n '8,+3p' /etc/passwd #打印/etc/passwd文件中第8行到第8行后面的3行,也就是到第11行
/模式1/,/模式2/:两个模式之间的行,当第二个模式匹配结束的时候又会从第一个模式继续匹配,直到文件最后
例:sed -n '/^b/,/^l/p' /etc/passwd #打印/etc/passwd文件中b开头的行到l开头的行之间的所有行
#,/模式1/:从第几行到匹配的模式的行
例:sed -n '3,/^f/p' /etc/passwd
(4) ~:步进
1~2:奇数行
例:sed -n '3~2p' /etc/passwd #从第3行开始,每次加2去继续处理,显示的都是奇数行,第一个数字是奇数那就是奇数,是偶数就是偶数
2~2:偶数行
例:sed -n '4~2p' /etc/passwd #从第4行开始,每次加2去继续处理,显示的都是偶数行
命令:
d:删除模式匹配的行
例:sed '20,30d' passwd #每从passwd文件中读入一行,sed就会查看是否是20,30之间的行,是的话就删除,不是就打印
sed '2~2d' passwd #这样也是打印奇数行的方法,因为我们删除了偶数行
p:打印匹配到的行,上边儿例子太多了,就不再举例了
&:表示前面模式当中匹配出的字符
sed -nr 's@^UUID@#&@p' /etc/fstab #将/etc/fstab文件中UUID开头的行全都注释
a [\]text:在指定行后面追加文本,相当于在下一行追加,指定了\的话就是在\后是要添加的文本
支持使用\n实现多行追加
例:cat passwd | sed -n '3,6a\=======' #在passwd文件的第3到6行后面追加==========字符
i [\]text:在指定行前面追加文本,相当于在上一行追加,指定了\的话就是在\后是要添加的文本
支持使用\n实现多行追加
例:sed -r '/^#[[:space:]]+S/i\++++++' ~/.bashrc #在~/.bashrc文件中以#开头并且后面跟了一个空格,空格后面有一个S的上一行追加+++++++字符
c [\]text:替换符合条件的行
例:sed -r '/^#[[:space:]]+S/c\++++++' ~/.bashrc #将~/.bashrc文件中以#开头并且后面跟了一个空格,空格后面有一个S的行替换为++++++++字符
w /PATH/FILE:将匹配的行存储到指定的文件中
例:sed -n '/^alias/w /app/alias.txt' ~/.bashrc #将~/.bashrc文件中以alias开头的行保存到/app/alias.txt文件中
r /PATH/FILE:读取指定文件的文本至模式中,匹配到行后
例:sed -n '/^alias/r /etc/centos-release' ~/.bashrc #在~/.bashrc文件中,以alias开头的每一行的下面添加/etc/centos-release文件中的内容
=:打印匹配的行的行号
例:sed '/^alias/=' ~/.bashrc #打印~/.bashrc文件中以alias开头的行的行号
!:取反
例:sed -n '/^alias/!p' ~/.bashrc #打印除了alias开头的所有行
sed -n '/bash$/!p' /etc/passwd #除了bash结尾的行都打印;
s///:搜索替代,支持使用其他分隔符,s@@@,s###
替换标记:
g:行内全局替换
p:显示替换成功的行
w /PATH/FILE:将替换成功的行保存至文件,要写文件的绝对路径
例:
(1) 将/etc/passwd中所有行尾是/bin/bash的替换为/sbin/nologin结尾
sed 's@/bin/bash$@/sbin/nologin@' /etc/passwd
(2) 将/etc/passwd中/bin/bash结尾的/bin前面添加+++,/bash后面添加===
sed -r 's@(/bin/bash)$@+++\1===@' /etc/passwd
(3) 将/etc/selinux/config中以SELINUX中开头的行后面替换为SELINUX=permissive
sed -r 's@^(SELINUX=).*@\1permissive@' /etc/selinux/config
(4) 使用sed命令取出IP地址
ifconfig ens33 | sed -nr '2s#.*inet[[:space:]]?(.*)[[:space:]]?netmask.*#\1#p'
(5) 将/etc/redhat-release中系统版本号取出来
sed -nr 's/.*release[[:space:]]?([^.]+)\..*/\1/p' /etc/redhat-release
(6) 写一个脚本,判断如果系统版本为7则在/etc/default/grub文件中的GRUB_CMDLINE_LINUX="rhgb quiet"这一行的quiet后面添加xxx字符,如果不是则打印版本号,以下是我自己的
想法
#!/bin/bash
number=$(sed -nr 's#.*release[[:space:]]?([^.]+).*#\1#p' /etc/redhat-release)
if [ $number -ge 7 ];then
`sed -i.bak -r 's/(.*\"rhgb quiet)(\")/\1xxx\2/' /etc/default/grub`
else
echo The system version is $number!
fi