2017-11-02
sed:行编辑器,按行处理;默认不做原文件修改,会在sed自身的模式空间中按行读相关的数据并完成编辑,然后显示到屏幕上
一. 基本用法:
1. 语法格式:
sed [option]... 'script' 文件名,其中script = '编辑位置+编辑命令' 注意:编辑位置要紧跟着编辑命令,中间没空格
2. option选项:(sed后面跟的参数,比如sed -n...)
-n:默认输出文件全部内容,加上-n就不会输出,可用于控制输出,一般和编辑命令p一起用,比如sed -n '3,5p' 1.txt 输出1.txt的3-5行;
-e: 多点编辑,用于一条命令中执行多个编辑操作;
-f /PATH/TO/SCRIPT_FILE: 从指定文件中读取编辑脚本;
-r: 支持使用扩展正则表达式;
-i: 直接修改文件内容;
3. 编辑位置选定:
(1) 不给位置:对全文进行处理;
(2) 单位置:
#: 指定的行,比如5表示第5行
/pattern/:被此处模式所能够匹配到的每一行;
(3) 位置范围:
![](https://images2017.cnblogs.com/blog/1268585/201711/1268585-20171110105558122-1437996802.png)
(4) 正则表达式匹配
4. 编辑命令:
d:删除,例如删除空白行sed '/^$/d' file;删除文件最后一行sed '$d' file
p:显示模式空间中的内容
a text:在指定行的下一行追加文本,text表示要加入的文本信息;支持使用
实现多行追加;
其中a和之间有没空格都可以,经验证不要也行,下面的同理
比如:sed '/^UUID/a hello,world.
welcome' /etc/fstab---在以UUID开头的行后面追加hello,world和 welcome两行信息
i text:在行前面插入文本;支持使用
实现多行插入;
c text:替换行为单行或多行文本为指定的信息,比如sed '/^UUID/c hello,world.
welcome' /etc/fstab;
w:保存模式空间匹配到的行至指定文件中;
比如sed '/^UUID/w /tmp/fstab.txt' /etc/fstab, 把etc/fstab以UUID开头的行,存到/tmp/fstab.txt中
r:读取指定文件的文本流至模式空间中匹配到的行的行后;
例如:sed '6r /etc/issue' /etc/fstab----把/etc/issue中的内容写到/etc/fstab文件的第6行后面
=:为模式空间中的行打印行号; sed '/^UUID/=' /etc/fstab 打印匹配到以UUID开头的行号
!:取反条件; 例如 sed '/^UUID/!d' /etc/fstab ---删除不是以UUID开头的行
s///:支持使用其它分隔符,s@@@,s###;--查找替换; 例如:sed 's#^UUID#uuid#' /etc/fstab
替换标记:
1)g: 行内全局替换,比如sed 's/girl/girls/g' file ;会替换每一行的所有匹配
2) 当需要从第N处匹配开始替换时,可以使用 /Ng
echo sksksk | sed 's/sk/SK/2g'
skSKSK
3)如只想替换第N处匹配,需要用/N
<body>hello the world! <body>中,把第2个body替换为</body>,所在的文件为test.txt
sed -r 's#(body)#/' test.txt
4)p: 显示替换成功的行;
5)w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中;
例子:
1)删除/boot/grub/grub.conf文件中所有以空白开头的行行首的空白字符;(centos7)
sed 's#^[[:space:]]+##' /etc/grub2.cfg
2)删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的#和空白字符;
sed 's@^#[[:space:]]+@@' /etc/fstab
3)在/etc/profile的最后一行附加两行文本name=hong;intro=hello,$name,如果不想使变量生效,用单引号,想立刻生效用双引号。
sed -i '$a
ame=hong
intro=hello,$name' /etc/profile
5. sed元字符集
^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
* 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] 匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
(..) 匹配子串,保存匹配的字符,如s/(love)able/1rs,loveable被替换成lovers。
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
> 匹配单词的结束,如/love>/匹配包含以love结尾的单词的行。
x{m} 重复字符x,m次,如:/0{5}/匹配包含5个0的行。
x{m,} 重复字符x,至少m次,如:/0{5,}/匹配至少有5个0的行。
x{m,n} 重复字符x,至少m次,不多于n次,如:/0{5,10}/匹配5~10个0的行。
说明
- (..)的例子,匹配某一段字符串,这里的其实是转义字符,默认sed不支持扩展正则表达式,如果用sed -r的话,转义字符可省去
1) echo this is digit 7 in a number | sed 's#digit ([0-9])#1#'
输出: this is 7 in a number
命令中 digit 7,被替换成了 7。样式匹配到的子串是 7,(..) 用于匹配子串,对于匹配到的第一个子串就标记为 1,依此类推匹配到的第二个结果就是 2,例如:
2) echo aaa BBB | sed 's/([a-z]+) ([A-Z]+)/2 1/'
2) echo aaa BBB | sed 's/([a-z]+) ([A-Z]+)/2 1/'
输出:BBB aaa
3) love被标记为1,所有loveable会被替换成lovers,并打印出来:sed -n 's/(love)able/1rs/p' file
- 关于&的例子
1)正则表达式 w+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词:
echo this is a test line | sed 's/w+/[&]/g'
echo this is a test line | sed 's/w+/[&]/g'
输出:[this] [is] [a] [test] [line]
2)所有以192.168.0.1开头的行都会被替换成它自已加localhost:
sed 's/^192.168.0.1/&localhost/' file
sed 's/^192.168.0.1/&localhost/' file
输出:192.168.0.1localhost
6. 高级编辑命令:
h: 把模式空间中的内容覆盖至保持空间中;(在模式空间中编辑,保持空间保存未编辑好的半成品数据,以便后面再处理)
H:把模式空间中的内容追加至保持空间中;
g: 从保持空间取出数据覆盖至模式空间;
G:从保持空间取出内容追加至模式空间;
x: 把模式空间中的内容与保持空间中的内容进行互换;
n: 读取匹配到的行的下一行至模式空间;(模式空间中只有匹配行的下一行,覆盖了匹配到的行)
N:追加匹配到的行的下一行至模式空间;(有2行)
d: 删除模式空间中的单行;
D:删除模式空间中的所有行;
几个例子:
sed -n 'n;p' FILE:显示偶数行 ---多个处理命令用分号隔开
sed '1!G;h;$!d' FILE:逆向显示文件内容-----
理解:1!表示第一行除外,$表示最后一行,!$表示除了最后一行,每一行都要执行这3个命令,然后才处理下一行,sed会首先读取一行到模式空间,然后执行这3个命令
sed '$!N;$!D' FILE: 取出文件后两行;
sed '$!d' FILE:取出文件最后一行;
sed 'G' FILE: 每一行后面追加一个空白行
sed '/^$/d;G' FILE: 如果是空白行,删掉,在后面再加一个空白行;表示把多个空白行合并为1个
sed 'n;d' FILE: 显示奇数行;
sed -n '1!G;h;$p' FILE: 逆向显示文件中的每一行;
sed '/test/{ n; s/aa/bb/; }' file 如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续:
sed '1,10y/abcde/ABCDE/' file 把1~10行内所有abcde转变为大写,y表示翻译,注意,正则表达式元字符不能使用这个命令:
sed '1,10y/abcde/ABCDE/' file 把1~10行内所有abcde转变为大写,y表示翻译,注意,正则表达式元字符不能使用这个命令: