文章目录
sed是一个流编辑器,用于对文件或输入流执行各种文本转换,功能强大且效率高。
主要用于对数据行进行替换、删除、新增、修改等。
一、sed 语法格式
sed [-nefri] 'command' 输入文本
参数选项
| 常见参数 | 说明 |
|---|
| -n | 抑制输出,结合p指令打印特定行。 默认sed会列出所有指定内容,加上 -n 参数后,则只有经过sed 特殊处理的那一行才会被列出来。 |
| -i | 直接修改文件内容,而且不进行任何输出,慎用! 默认情况下 sed 并不直接修改文件内容,只是把结果进行标准输出,文件内容实际没有变化。 |
| -e | 使用后面的动作指令编辑文件内容 |
| -f | 直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作; |
动作指令
使用时要用单引号把动作指令内容括起来;
若指令内容包含变量,则用双引号括起来。
| 常用动作 | 说明 |
|---|
| p | print,打印,列出指定的内容,通常与 -n 参数一起使用 |
| a | after,新增,后面接字符串,并显示在新的一行(目前的下一行) |
| i | insert,插入, 后面接字符串,并显示在新的一行(目前的上一行) |
| c | change,替换一行或多行的整行内容,后面接字符串,用于取代 n1,n2 之间的行 |
| s | supersede,stead,替换一行或多行中的部分内容,通常搭配正规表达式 常用方式: 1,20s/old/new/g |
| d | delete,删除,后面通常不接任何字符 |
二、参数使用举例
(假设我们有一文件名为input)
1、输入文件的几种方式
sed 命令中的文件参数可以是文件名,也可以是来自管道的输入。
下面几种方式是等价的:
sed 's/hello/world/g' input > output
sed 's/hello/world/g' < input> output
cat input | sed 's/hello/world/g' - > output
cat input | sed 's/hello/world/g' > output # - 可以省略
2、-n 抑制输出
默认情况下,sed打印所有已处理的输入(已通过命令修改/删除的输入除外)。
使用 -n 抑制输出,结合p指令可以打印特定行。
仅打印输入文件的第45行:
sed -n '45p' input
3、-i 修改文件内容且不进行输出
查看input文件原内容:
$ cat input
hello ehllo hello
hello abadbsabf
a123gdsgahello
sed 不带 -i 参数时进行替换指令
会输出替换后的结果,且再次查看input内容,原文件未修改。
# sed 替换
$ sed 's/hello/world/' input
world ehllo hello
world abadbsabf
a123gdsgaworld
# 查看input内容,并未真正修改
$ cat input
hello ehllo hello
hello abadbsabf
a123gdsgahello
sed -i 进行替换指令
不会输出任何内容,且再次查看input内容,原文件直接被修改了。
$ sed -i 's/hello/world/' input
$ cat input
world ehllo hello
world abadbsabf
a123gdsgaworld
sed -i 使用正则表达式匹配
$ cat input.txt
google.
taobao.
zhihu-
$ sed -i 's/\.$/\!/g' input.txt
$ cat input.txt
google!
taobao!
zhihu-
(这个命令把选项 -i 和指令 a 结合使用,同时其中 $ 代表最后一行,从而实现直接修改文件,在最后一行后面新增内容。)
$ sed -i '$a # This is a test' input.txt
$ cat input.txt
google!
taobao!
zhihu-
# This is a test
4、-e 和 -f 指定脚本
4.1 语法:
-e 指定动作集(两种方式一样):
-e script
–expression=script
-f 指定动作文件(两种方式一样):
-f script-file
–file=script-file
4.2 下面几种示例是等价的:
sed 's/hello/world/' input.txt > output.txt
sed -e 's/hello/world/' input.txt > output.txt
sed --expression='s/hello/world/' input.txt > output.txt
echo 's/hello/world/' > myscript.sed
sed -f myscript.sed input.txt > output.txt
sed --file=myscript.sed input.txt > output.txt
4.3 使用 -e实现多个匹配
默认情况下,一条sed命令只能有一个编辑指令;
若要实现同时执行多个编辑指令,有如下几种方式:
通过 -f 指定脚本文件,在文件中集合多条指令;
通过管道符|连接多条 sed 指令;
- 在一条sed指令中使用多个
-e选项实现。
在一条sed命令中,删除/etc/passwd第三行到末尾的数据,并把bash替换为blueshell:
$ nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'
1 root:x:0:0:root:/root:/bin/blueshell
2 daemon:x:1:1:daemon:/usr/sbin:/bin/sh
三、各指令使用举例
1、p 打印某行
| 命令 | 说明 |
|---|
| sed ‘1p’ filename | 先打印第一行,然后再打印所有行 |
| sed -n ‘1p’ filename | 打印第一行 |
| sed -n ‘$p’ filename | 打印最后一行 |
| sed -n ‘1,2p’ filename | 打印第一行到第二行 |
| sed -n ‘2,$p’ filename | 打印第二行到最后一行 |
| sed ‘/yuance/p’ filename | 先打印包含yuance的行,再打印所有行 |
| sed -n ‘/yuance/p’ filename | 打印包含yuance的行 |
| sed -n ‘/$/p’ filename | 打印包括关键字 $ 所在的行,使用反斜线 \ 屏蔽特殊含义 |
2、d删除某行
d --delete, 可指定区间,‘1,Nd’
与 p指令用法类似
- 默认会打印出删除指定行后,其它行的内容,但是原文件内容不变
| 命令 | 说明 |
|---|
| sed ‘3d’ filename | 删除第三行 |
| sed ‘$d’ filename | 删除最后一行 |
| sed ‘1,2d’ filename | 删除第一行到第二行 |
| sed ‘2,$d’ filename | 删除第二行到最后一行 |
| sed ‘/pattern/d’ filename | 删除包含pattern关键字的所有行 |
$ cat input
world ehllo hello
world abadbsabf
a123gdsgaworld
1241
$ sed '4d' input
world ehllo hello
world abadbsabf
a123gdsgaworld
$ cat input
world ehllo hello
world abadbsabf
a123gdsgaworld
1241
3、a增加一行或多行字符串(在下一行)
| 命令 | 说明 |
|---|
| sed ‘1a drink tea’ filename | 第一行后增加字符串"drink tea" |
| sed ‘1,3a drink tea’ filename | 第一行到第三行后增加字符串"drink tea" |
| sed ‘$a drink bye’ filename | 最后一行后增加字符串"bye" |
| sed ‘1a drink tea\nor coffee’ filename | 第一行后增加两行"drink tea"和"or coffee" |
| sed ‘1a drink tea’ filename | 第一行后增加字符串"drink tea" |
$ cat input.txt
Hello!
jing is me,welcome to my blog.
end
第一行后增加字符串"drink tea"
$ sed '1a drink tea' input.txt
Hello!
drink tea
jing is me,welcome to my blog.
end
第一行到第三行后增加字符串"drink tea"
$ sed '1,3a drink tea' input.txt
Hello!
drink tea
jing is me,welcome to my blog.
drink tea
end
drink tea
增加多行,使用换行符 "\n"
$ sed '1a drink tea\nor coffee' input.txt
Hello!
drink tea
or coffee
jing is me,welcome to my blog.
end
4、i插入一行或多行(在上一行)
todo
5、c对一行或多行进行整行替换
第一行代替为 "Hi"
$ sed '1c Hi' input.txt
Hi
jing is me,welcome to my blog.
end
第一行到第二行代替为 "Hi"
$ sed '1,2c Hi' ab
Hi
end
将第2-5行的内容取代成为"No 2-5 number"(其中"nl"是带行号输出):
$ nl /etc/passwd | sed '2,5c No 2-5 number'
1 root:x:0:0:root:/root:/bin/bash
No 2-5 number
6 sync:x:5:0:sync:/sbin:/bin/sync
.....(后面省略).....
6、s替换一行中的部分内容
6.1 格式 ‘s/xx/xx/g’:
sed 's/要替换的字符串/新的字符串/g' (要替换的字符串可以用正则表达式)
| 命令 | 说明 |
|---|
| sed ‘s/cat/bird/g’ filename | 把文件中所有的’cat’替换成’bird’ |
| sed ‘s/cat//g’ filename | 删除文件中所有的’cat’(替换为空即删除) |
| sed ‘s/unix/linux/’ filename | 把每一行中的第 1 次出现的’unix’替换成’linux’ |
| sed ‘s/unix/linux/3’ filename | 把每一行中的第 3 次出现的’unix’替换成’linux’ |
| sed ‘s/unix/linux/4g’ filename | 把每一行中第 4 次开始到最后出现的’unix’全部替换成’linux’ |
| sed ‘3 s/unix/linux/’ filename | 在’s’前加数字,可对指定行进行替换。 把第 3 行中第一次出现的’unix’替换成’linux’。 |
| sed ‘3,7 s/unix/linux/’ filename | 在’s’前也可以加数字范围,对多行进行替换。 把第 3-7 行中第一次出现的’unix’替换成’linux’。 |
| sed ‘3,$ s/unix/linux/’ filename | 把第 3行至结尾行每行第一次出现的’unix’替换成’linux’。 |
| nl filename | sed -n ‘7 s/unix/linux/p’ | 把第 7 行中第一次出现的’unix’替换成’linux’,并把替换后的第7行打印出来。 若加了 -n 不加的后面的 p ,则替换后不打印。 |
6.2 匹配字符串中使用正则表达式
| 原字符串 | 命令 | 匹配结果 |
|---|
| inet addr:192.168.1.100 | sed 's/^.*addr://g’ | 192.168.1.100 |
| 192.168.1.100 Bcast:192.168.1.255 | sed 's/Bcast.*$//g’ | 192.168.1.100 |
| hello world | sed 's/^/#/g’ | #hello world,即在每行开头加上 # |
| hello world | sed 's/$/—/g’ | hello world---,即在每行最后加上 — |
6.3 替换匹配行中的某个字符串
sed '/匹配字符串/s/替换源字符串/替换目标字符串/g' filename
先进行字符串匹配;
然后对匹配到的行进行字符串替换。