sed是stream editor的缩写,意为流编辑器。它是面向字符流的,输入的字符流经过sed的处理后输出。sed可以对输入流或者文本进行插入,删除,替换操作。sed是按行进行处理的,默认的是进行全文所有的行进行处理。也可以进行模式匹配,即在模式匹配上的行进行操作。
sed命令的语法如下所示:
sed [options] script filename
同大多数Linux命令一样,sed也是从stdin中读取输入,并且将输出写到stdout,但是当filename被指定时,则会从指定的文件中获取输入,输出可以重定向到文件中,但是需要注意的是,该文件绝对不能与输入的文件相同。
options是指sed的命令行参数,这一块并不是重点,参数也不多。
script是指需要对输入执行的一个或者多个操作指令(instruction),sed会依次读取输入文件的每一行到缓存中并应用script中指定的操作指令,因此而带来的变化并不会影响最初的文件(注:如果使用sed时指定-i参数则会影响最初的文件)。如果操作指令很多,为了不影响可读性,可以将其写到文件中,并通过-f参数指定scriptfile:
sed -f scriptfile filename
在sed的替换操作中,其script的格式如下。
[address]s/pattern/replacement/flags
其中,[address]的作用是指定要进行替换操作的行。
1. 若没有[address],则说明要对每一行进行替换操作。
2. 若[address]是一个正则表达式,说明只对符合正则表达式的行进行替换操作。
3. 若[address]只指定了一个地址,说明只对该地址进行替换操作。
4. 若[address]指定了两个地址,说明是对这两个地址之间的行(包括这两个地址)进行替换操作。
s的意思是告诉sed是进行替换(substitute)操作。pattern是要被替换的内容,可以是正则表达式的形式。replacement是替换的内容。flags是替换的标识。
1. 若flags没有,则只替换一个匹配的地方。
2. 若flags是一个数字n(取值范围1-512),表明仅替换前n个被pattern匹配的内容。
3. 若flags是符号g,表明是替换改行所有匹配到的内容。
4. 若flags是ng,表明是从第n处开始替换。
比如说,有如下一个文本。
%%bash
cat sed_sample.txt
赏花归去马如飞,
去马如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
我们假设要替换样本文件中的所有“马”字,改成“牛”。则可以如下操作
%%bash
sed 's/马/牛/g' sed_sample.txt
赏花归去牛如飞,
去牛如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
或者只修改第2行的马字,修改成牛字。
%%bash
sed '2s/马/牛/g' sed_sample.txt
赏花归去马如飞,
去牛如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
在sed的行替换操作中,其script的格式如下。
[address]c\text
其中,[address]的用法和替换操作一样。 text是要进行替换的内容。该指令的意思是,将匹配的行替换成文本text
例如,将第一行到第三行替换成“这是一个行替换”。
%%bash
sed '1,3c\这是一个行替换' sed_sample.txt
这是一个行替换
醒时已暮赏花归。
在sed的删除操作中,其script的格式如下。
[address]d
其中,[address]的用法和在替换操作中的一样。d是删除标识。
比如,我们要删除文本的前两行。
%%bash
sed '1,2d' sed_sample.txt
酒力微醒时已暮,
醒时已暮赏花归。
或者删除带 “花”字的行。
%%bash
sed '/花/d' sed_sample.txt
去马如飞酒力微;
酒力微醒时已暮,
有人会问,那我只想删除文本中的”花”字,而不是删除整行,那该如何做?这其实只要将”花”字替换成空即可。
%%bash
sed 's/花//g' sed_sample.txt
赏归去马如飞,
去马如飞酒力微;
酒力微醒时已暮,
醒时已暮赏归。
删除空白行
%%bash
echo -e "未操作前:"
cat sed_sample.txt
echo -e "\n\n操作后:"
sed '/^$/d' sed_sample.txt
未操作前:
赏花归去马如飞,
去马如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
操作后:
赏花归去马如飞,
去马如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
其中,^代表一行的开始,$代表一行的结束。
sed 的插入和追加操作如下:
插入
[line-address]i\text
在匹配行的前方插入文本
追加
[line-address]a\text
在匹配行的后方插入文本
例如,在文本的最开始,插入“你好”,在文本的最后,插入,“再见”
%%bash
sed '1i\你好' sed_sample.txt
你好
赏花归去马如飞,
去马如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
%%bash
sed '$a\再见' sed_sample.txt
赏花归去马如飞,
去马如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
再见
sed 还有如下的操作。
名称 | 命令 | 语法 | 说明 |
---|---|---|---|
替换 | s | [address]s/pattern/replacement/flags | 替换匹配的内容 |
删除 | d | [address]d | 删除匹配的行 |
插入 | i | [line-address]i\text | 在匹配行的前方插入文本 |
追加 | a | [line-address]a\text | 在匹配行的后方插入文本 |
行替换 | c | [address]c\text | 将匹配的行替换成文本text |
打印行 | p | [address]p | 打印在模式空间中的行 |
打印行号 | = | [address]= | 打印当前行行号 |
打印行 | l | [address]l | 打印在模式空间中的行,同时显示控制字符 |
转换字符 | y | [address]y/SET1/SET2/ | 将SET1中出现的字符替换成SET2中对应位置的字符 |
读取下一行 | n | [address]n | 将下一行的内容读取到模式空间 |
读文件 | r | [line-address]r file | 将指定的文件读取到匹配行之后 |
写文件 | w | [address]w file | 将匹配地址的所有行输出到指定的文件中 |
退出 | q | [line-address]q | 读取到匹配的行之后即退出 |
[options]指令最常见的有
-n∶使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到萤幕上。但如果加上 -n 参数后 ,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e∶直接在指令列模式上进行 sed 的动作编辑;
-f∶直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作;
-r∶sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
-i∶直接修改读取的档案内容,而不是由萤幕输出。
-n 的使用效果如下
%%bash
sed -n 's/马/牛/g' sed_sample.txt
cat sed_sample.txt
赏花归去马如飞,
去马如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
-i 的使用效果如下
%%bash
sed -i 's/马/牛/g' sed_sample.txt
cat sed_sample.txt
赏花归去牛如飞,
去牛如飞酒力微;
酒力微醒时已暮,
醒时已暮赏花归。
%%bash
sed --help
用法: sed [选项]... {脚本(如果没有其他脚本)} [输入文件]...
-n, --quiet, --silent
取消自动打印模式空间
-e 脚本, --expression=脚本
添加“脚本”到程序的运行列表
-f 脚本文件, --file=脚本文件
添加“脚本文件”到程序的运行列表
--follow-symlinks
直接修改文件时跟随软链接
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if SUFFIX supplied)
-l N, --line-length=N
指定“l”命令的换行期望长度
--posix
关闭所有 GNU 扩展
-r, --regexp-extended
在脚本中使用扩展正则表达式
-s, --separate
将输入文件视为各个独立的文件而不是一个长的连续输入
-u, --unbuffered
从输入文件读取最少的数据,更频繁的刷新输出
-z, --null-data
separate lines by NUL characters
--help 打印帮助并退出
--version 输出版本信息并退出
如果没有 -e, --expression, -f 或 --file 选项,那么第一个非选项参数被视为
sed脚本。其他非选项参数被视为输入文件,如果没有输入文件,那么程序将从标准
输入读取数据。
GNU版sed主页: 。
使用GNU软件所需帮助文档: 。
将错误报告通过电子邮件发送到:.
请务必将单词“sed”放在标题的某处。