文本三剑客之sed的用法
第1章 Sed命令
1.1 sed 命令执行过程
1.2 sed介绍
sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后读入下行,执行下一个循环。如果没有使诸如‘D’的特殊命令,那会在两个循环之间清空模式空间,但不会清空保留空间。这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出或者-i进行修改。
1.3 sed功能
功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
参考:http://www.gnu.org/software/sed/manual/sed.html
1.4 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命令的指示信息 p print 输出信息 i insert 输入信息,在指定信息前面插入新的信息 a append 附加信息,在指定信息后面附加新的信息 d delete 删除指定信息 s substitute 替换信息 s###g(全局替换) c 替换修改指定的一整行信息
使用sed查找文件的行
1 行号 3p # p print 打印输出
2 连续的行号 3,5p # 输出第3行到第5行 ,表示序列
3 过滤找出包含xxx的行 /oldboy/p # 按照匹配字符串的方式模式查找
4 过滤范围 //,//p
示例1:输出打印文件的第三行
[root@oldboyedu-lnb ~]# sed -n '3p' oldboy.txt test
示例2:输出文件的3-6行 包含空行
格式: sed 'n,np' file
sed '3,6p' file
[root@oldboyedu-lnb ~]# sed -n '3,6p' oldboy.txt test I like badminton ball ,billiard ball and chinese chess! my blog is http: blog.51cto.com
示例3: 输出文件的最后一行 $
[root@oldboyedu-lnb ~]# sed -n '$p' oldboy.txt 11111111818181818 [root@oldboyedu-lnb ~]# sed -n '15,$p' oldboy.txt hehe $m 11111111818181818
示例4:取出网卡的第二行
[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p' inet 10.0.0.200 netmask 255.255.255.0 broadcast 10.0.0.255
示例5:根据行号信息,输出多行内容(不连续)
[root@oldboyedu ~]# sed -n '1p;3p' person.txt 101,oldboy,CEO 103,Alex,COO
根据内容信息,输出多行内容(连续)
示例6: #将有oldboy到alex行的信息都输出出来
[root@oldboyedu ~]# sed -n '/oldboy/,/Alex/p' person.txt 101,oldboy,CEO 102,zhaoyao,CTO 103,Alex,COO
示例7:#将有oldboy和alex行的信息都输出出来
[root@oldboyedu ~]# sed -n '/oldboy/p;/Alex/p' person.txt 101,oldboy,CEO 103,Alex,COO 106,oldboy,CIO
示例8:在文件第一行添加信息
[root@oldboyedu ~]# sed '1i100,oldgirl,UFO' person.txt 100,oldgirl,UFO 101,oldboy,CEO 102,zhaoyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO 106,oldboy,CIO
示例9:在文件最后一行添加信息
[root@oldboyedu ~]# sed '$a108,oldgirl,UFO' person.txt 100,oldgirl,UFO 101,oldboy,CEO 102,zhaoyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO 106,oldboy,CIO 108,oldgirl,UFO
测试:
01. 在第三行后面添加oldboy.txt信息
sed '3aoldboy.txt' person.txt
02. 在第二行前面添加oldboy.txt信息
sed '2ioldboy.txt' person.txt
03. 在有oldboy行的前面添加oldgirl 后面添加olddog信息
sed -e '/oldboy/ioldgirl' -e '/oldboy/aolddog' person.txt
创建测试环境:
-rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy01.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy02.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy03.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy04.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy05.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy06.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy07.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy08.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy09.txt -rw-r--r--. 1 root root 0 Oct 10 02:10 oldboy10.txt
批量修改文件的扩展名称 将oldboyxx.txt扩展名修改为oldboyxx.jpg
[root@oldboyedu oldboy]# ls oldboy*.txt|sed -r 's#(.*)txt#mv &(表示oldboy*.txt) \1(表 示oldboy*)jpg#g' mv oldboy01.txt oldboy01.jpg mv oldboy02.txt oldboy02.jpg mv oldboy03.txt oldboy03.jpg mv oldboy04.txt oldboy04.jpg mv oldboy05.txt oldboy05.jpg mv oldboy06.txt oldboy06.jpg mv oldboy07.txt oldboy07.jpg mv oldboy08.txt oldboy08.jpg mv oldboy09.txt oldboy09.jpg mv oldboy10.txt oldboy10.jpg mv oldboy.txt oldboy.jpg
1.5 sed 的模糊匹配
语法格式:
grep '过滤的内容' file
sed '/过滤的内容/动作' file
sed的增删改查之查看过滤文件内容
示例1:过滤包含http的行
[root@oldboyedu-lnb ~]# sed -n '/http/p' oldboy.txt my blog is http: blog.51cto.com our site is http:www.lizhenya.com
示例2: 过滤包含http或lizhenya的行使用或者|
语法格式:
格式: sed 'n,np' file
sed '3,6p' file
[root@oldboyedu-lnb ~]# sed -nr '/http|lizhenya/p' oldboy.txt I am lizhenya teacher! my blog is http: blog.51cto.com our site is http:www.lizhenya.com lizhenyalizhenyalizhenyaaaaaaaaa
示例3: 过滤字符串的区间 使用行可以过滤区间 sed '1,3p' file
语法格式:
sed '/字符串/,/字符串/p' file
[root@oldboyedu-lnb ~]# sed -n '/test/,/not/p' oldboy.txt test I like badminton ball ,billiard ball and chinese chess! my blog is http: blog.51cto.com our site is http:www.lizhenya.com my qq num is 593528156 aaaa, not 572891888887.
工作中匹配日志时间区间
[root@oldboyedu-lnb ~]# sed -n '/Aug 6 08:09:26/,/Aug 7 08:09:23/p' /var/log/messages
区间模糊匹配的注意事项:
a)模糊匹配的结束字符 如果文件的后面有多个相同的字符 以第一个为结界
b)模糊匹配的开始字符 如果文件匹配字符结束 后还有开始的字符 没有结束的字符 则匹配内容到文件的末尾
1.6 sed 增加内容模式
sed 增加内容 临时增加内容 只输出到屏幕上 不会更改源文件
vi vim echo cat
-a append 追加 # 在当前行的下一行追加内容 当前3 第4行插入的新的内容
-i insert 插入 # 在当前行插入内容 当前3 插入3行前的内容
-c change 替换 # 把当前行的内容进行替换
语法格式:
sed '3a 插入的内容' file
示例1: 在当前行插入
[root@oldboyedu-lnb ~]# sed '3i alex' oldboy.txt.bak I am lizhenya teacher! I teach linux. hehe test
示例2: 在当前行追加新的内容
[root@oldboyedu-lnb ~]# sed '3a prot=9777' oldboy.txt.bak I am lizhenya teacher! I teach linux. test prot=9777
[root@oldboyedu-lnb ~]# sed '3,5a alex' oldboy.txt.bak I am lizhenya teacher! I teach linux. test alex alex I like badminton ball ,billiard ball and chinese chess! alex
示例3: 替换第3行的内容为oldboyedu.com 替换整行
[root@oldboyedu-lnb ~]# sed '3c oldboyedu.com' oldboy.txt.bak I am lizhenya teacher! I teach linux. oldboyedu.com
案例: 修改selinux的配置文件selinux=disabled
语法格式: sed -n '/模式/动作' file
sed -n '/被替换的内容/c 替换的内容' file
[root@oldboyedu-lnb ~]# sed -n '/^SELINUX=/c SELINUX=enforcing' /etc/selinux/config SELINUX=enforcing [root@oldboyedu-lnb ~]# sed -in '/^SELINUX=/c SELINUX=enforcing' /etc/selinux/config [root@oldboyedu-lnb ~]# sed -n '/^SELINUX=/c SELINUX=disabled' /etc/selinux/config SELINUX=disabled
方法2 按照行替换
[root@oldboyedu-lnb ~]# sed -n '8c SELINUX=disabled' /etc/selinux/config SELINUX=disabled [root@oldboyedu-lnb ~]# sed -in '8c SELINUX=disabled' /etc/selinux/config [root@oldboyedu-lnb ~]# sed 'a oldboyedu.com' oldboy.txt.bak 了解 I am lizhenya teacher! oldboyedu.com I teach linux. oldboyedu.com test oldboyedu.com
1.7 sed的删除
语法结构:
sed '/模式/动作' file # 不加参数只是临时删除 不影响源文件
sed '3d' file
sed '/oldboy/d' file
示例1: 删除第三行
[root@oldboyedu-lnb ~]# sed '3d' oldboy.txt.bak I am lizhenya teacher! I teach linux.
示例2: 删除1-3行
[root@oldboyedu-lnb ~]# sed '1,3d' oldboy.txt.bak [root@oldboyedu-lnb ~]# sed '1,$d' oldboy.txt.bak
示例3: 字符匹配删除 删除包含linux的行
[root@oldboyedu-lnb ~]# sed '/linux/d' oldboy.txt.bak
示例4: 删除匹配的区间
[root@oldboyedu-lnb ~]# sed '/test/,/our/d' oldboy.txt.bak I am lizhenya teacher! I teach linux. my qq num is 593528156
1.8 sed 的内容替换
语法格式:
sed 's#被替换内容#替换成什么#g' file
's@@@g'
's///g'
s sub
g global 全局替换
示例1: 替换文件中的每行第一个test为oldboy 了解
s### 替换文件中每行的第一个test
sed 's###' 类似于 vim中的 %s###
[root@oldboyedu-lnb ~]# sed 's#test#oldboyedu.com#' oldboy.txt.bak I am lizhenya teacher! I teach linux. oldboyedu.com test test test
示例2: 替换文件中所有的test为oldboyedu.com
sed 's###g' file
[root@oldboyedu-lnb ~]# sed 's#test#oldboyedu.com#g' oldboy.txt.bak
永久替换
[root@oldboyedu-lnb ~]# sed -i 's#test#oldboyedu.com#g' oldboy.txt.bak
示例3:把文件第2,5行中的小写字母删除 有n 必须有p 才能输出结果
[root@oldboyedu-lnb ~]# sed -n '3,5p' oldboy.txt.bak|sed 's#[a-z]##g' . . . . I ., ! [root@oldboyedu-lnb ~]# sed -n '3,5s#[a-z]##gp' oldboy.txt.bak . . . . I ., !
1.9 sed替换的注意事项:
s### s/// 看文件中是否存在### ///
[root@oldboyedu-lnb ~]# head -1 passwd |sed 's//root/test/g' sed: -e expression #1, char 9: unknown option to `s' [root@oldboyedu-lnb ~]# head -1 passwd |sed 's/\/root/test/g' root:x:0:0:root:test:/bin/bash [root@oldboyedu-lnb ~]# [root@oldboyedu-lnb ~]# head -1 passwd |sed 's#/root#test#g' root:x:0:0:root:test:/bin/bash [root@oldboyedu-lnb ~]# head -1 passwd |sed 's#\#hehe#test#g' root:x:test0:0:root:/root:/bin/bash
1.10 sed 的后向引用
语法格式: 先保护 后引用
() 引用()中的内容 支持正则
\1 表示第一个()的内容
\2 表示第二个()的内容
调用()内容的前面和后面可以加任意的内容
[root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#\1#g' 123456 [root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#<<\1>>#g' <<123456>> [root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#hehe\1hehe#g' hehe123456hehe [root@oldboyedu-lnb ~]# echo 123456|sed -r 's#(.*)#1111\11111#g' 11111234561111 [root@oldboyedu-lnb ~]# echo 123456|sed -r 's#([0-9]{3})#\1#g' 123456 [root@oldboyedu-lnb ~]# echo 123456|sed -r 's#([0-9]{3})#<\1>#g' <123><456> [root@oldboyedu-lnb ~]# echo 123456|grep '[0-9]{3}' -o [root@oldboyedu-lnb ~]# echo 123456|egrep '[0-9]{3}' -o 123 456
案例: sed 后向引用获取IP地址
[root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#^.*inet (.*) netmask.*$#\1#g' 10.0.0.200 [root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*inet )(.*) netmask.*$#\1#g' inet [root@oldboyedu-lnb ~]# ifconfig eth0|sed –n '2p'|sed-r's#(^.*inet )(.*)( netmask.*$)#\3#g' netmask 255.255.255.0 broadcast 10.0.0.255 [root@oldboyedu-lnb ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*inet )(.*)( netmask.*$)#\2#g' 10.0.0.200
使用ip add 取出IP地址和子网掩码
[root@oldboyedu-lnb ~]# ip add|grep -n . [root@oldboyedu-lnb ~]# ip add|sed -nr '9s#^.*net (.*)/24.*$#\1#gp' 10.0.0.200 [root@oldboyedu-lnb~]# ip add |sed -n '9p' |sed -r 's#^.*brd(.*)scop.*$#\1#g' 10.0.0.255 [root@oldboyedu-lnb~]# ip add |sed -nr '9s#^.*brd(.*)scop.*$#\1#gp' 10.0.0.255
1.11 练习题
1.11.1 将/etc/passwd文件的第3行到第7行另存为/tmp/passwd
[root@oldboyedu-lnb~]# cat /etc/passwd |sed -n '3,7p' > /tmp/passwd [root@oldboyedu-lnb~]# cat /tmp/passwd 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
1.11.2 在/tmp/passwd文件中的第3行前插入下面两行文字
good good study, day day up.
Come here, change yourself.
[root@oldboyedu-lnb~]# sed '3i\ngood good study, day day up.\nCome here,change yourself.' /tmp/passwd daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin ngood good study, day day up. Come here,change yourself. 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
1.11.3 将/tmp/passwd文件中的所有/sbin/nologin替换为/bin/bash
[root@oldboyedu-lnb~]# sed -n 's#/sbin/nologin#/bin/bash#gp' /tmp/passwd daemon:x:2:2:daemon:/sbin:/bin/bash adm:x:3:4:adm:/var/adm:/bin/bash lp:x:4:7:lp:/var/spool/lpd:/bin/bash
1.11.4 删除/tmp/passwd文件中包含bin单词的行
[root@oldboyedu-lnb~]# sed '/\<bin\>/d' /tmp/passwd1 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 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
1.12 小结sed
增删改查替换
查看:
-n 取消默认输出 -r 支持扩展正则 -i 更改源文件 sed -n '3p' file 1,3p 3,$p sed -n '/root/p' file sed -n '/root/,/alex/p' file
增加替换:
-i -a -c sed '3i 新的内容' file sed '3a 追加内容' file sed '3c 替换整行内容' file
组合使用:
sed '3,5c oldboyedu' file sed '/root/c oldboyedu' file 修改源文件 -i参数 sed的替换: sed 's#替换谁#替换的内容#g' file cat file |sed 's###g' sed '3,5p' file|sed 's###g' 组合使用 sed -n '3,5s###gp' file sed的后向引用 sed -r 's#()#\1#g'
PS: Linux中大部分的命令 -V 都是查看版本信息
grep的参数 -n 显示匹配到内容的行号 -v 取反 -o 显示匹配过程 -i 不区分大小写 -E 支持扩展正则 -R 递归查询文件内容 -w 过滤单词 -c 统计字符串在文件中出现的次数 -A 显示当前查找到的内容往下n行 了解 -B 显示当前查找到的内容往上n行 了解 -C 显示当前查找到的内容上下各n行 了解
[root@oldboyedu-lnb ~]# grep oldboy 1.txt alexoldboylidao oldboy oldboyedu.com [root@oldboyedu-lnb ~]# grep -w oldboy 1.txt oldboy [root@oldboyedu-lnb ~]# grep linux -A3 oldboy.txt.bak I teach linux. oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com I like badminton ball oldboyedu.com,billiard ball and chinese chess! [root@oldboyedu-lnb ~]# grep like -B3 oldboy.txt.bak I teach linux. oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com I like badminton ball oldboyedu.com,billiard ball and chinese chess! [root@oldboyedu-lnb ~]# grep linux -C1 oldboy.txt.bak I am lizhenya teacher! I teach linux. oldboyedu.com oldboyedu.com oldboyedu.com oldboyedu.com