参考资料
目录
一. 基本语法
sed [选项] '命令' 文件名
1.1 选项
选项名称 | 说明 |
---|---|
-e | 同时执行多个命令 |
-i | 直接对原文件进行操作 |
-n | 抑制自动输出,常和 p 命令共同使用,指定输出的行 |
-E | 正则表达式 |
-s | 将输入的多个文件视为独立的文件进行处理,而不是将它们作为一个单一的输入流来处理。 |
1.2 命令
命令名称 | 对应单词 | 说明 |
---|---|---|
s | substitution | 字符串替换 |
a | append | 在匹配行后面追加 |
i | insert | 在匹配行前面插入 |
d | delete | 删除指定行 |
p | 打印匹配行(通常与 -n 选项一起使用) | |
c | change | 整行替换 |
r | read | 将文件的内容读入 |
w | write | 将文本写入文件 |
二. 选项用法
2.1 -e 同时执行多个命令
⏹将你好
替换为你好啊
,同时也将hello
替换为こんにちは
fengyehong@ubuntu:~$ echo -e "你好,世界\nhello,world"
你好,世界
hello,world
fengyehong@ubuntu:~$ echo -e "你好,世界\nhello,world" | sed -e 's#你好#你好啊#' -e 's/hello/こんにちは/'
你好啊,世界
こんにちは,world
2.2 -i 对原文件进行操作
⏹未使用-i
配置项之前,使用sed命令进行替换,并不会影响到原文件。
fengyehong@ubuntu:~$ cat my_info.csv
你好,世界
hello,world
fengyehong@ubuntu:~$ sed 's#hello#こんにちは#' my_info.csv
你好,世界
こんにちは,world
fengyehong@ubuntu:~$ cat my_info.csv
你好,世界
hello,world
⏹使用-i
配置项之后,sed命令的结果不会打印到控制台,会直接反映到原文件上。
fengyehong@ubuntu:~$ sed -i 's#hello#こんにちは#' my_info.csv
fengyehong@ubuntu:~$
fengyehong@ubuntu:~$ cat my_info.csv
你好,世界
こんにちは,world
2.3 -n 抑制自动输出,配合p输出指定行
⏹输出1~3行
fengyehong@ubuntu:~$ cat my_info.csv
111,----------,11111111
222,----------,22222222
333,----------,33333333
444,----------,44444444
555,----------,55555555
666,----------,66666666
fengyehong@ubuntu:~$
fengyehong@ubuntu:~$ sed -n '1,3p' my_info.csv
111,----------,11111111
222,----------,22222222
333,----------,33333333
⏹输出第3行
fengyehong@ubuntu:~$ sed -n '3p' my_info.csv
333,----------,33333333
⏹输出第1行和第3行
fengyehong@ubuntu:~$ sed -n -e '1p' -e '3p' my_info.csv
111,----------,11111111
333,----------,33333333
fengyehong@ubuntu:~$ sed -n '1p;3p' my_info.csv
111,----------,11111111
333,----------,33333333
⏹输出最后一行
fengyehong@ubuntu:~$ sed -n '$p' my_info.csv
666,----------,66666666
2.4 -E 正则表达式
⏹输出包含香蕉
或苹果
所在的行
fengyehong@ubuntu:~$ cat my_info.csv
111,--香蕉------,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
?55,-----香蕉---,55555555
666,----------,66666666
fengyehong@ubuntu:~$
fengyehong@ubuntu:~$ sed -n -E '/香蕉|苹果/p' my_info.csv
111,--香蕉------,11111111
444,---苹果----,44444444
?55,-----香蕉---,55555555
⏹输出包含香蕉
或苹果
所在的行之后,将数字开头的第一个数字给替换为***
fengyehong@ubuntu:~$ sed -n -E '/香蕉|苹果/p' my_info.csv
111,--香蕉------,11111111
444,---苹果----,44444444
?55,-----香蕉---,55555555
fengyehong@ubuntu:~$
fengyehong@ubuntu:~$ sed -n -E '/香蕉|苹果/p' my_info.csv | sed -E 's/^[0-9]/***/'
***11,--香蕉------,11111111
***44,---苹果----,44444444
?55,-----香蕉---,55555555
2.5 -s 将输入的多个文件视为独立的文件进行处理
👉有文件内容如下👈
fengyehong@ubuntu:~$ cat my_info.csv
111,--香蕉------,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
fengyehong@ubuntu:~$
fengyehong@ubuntu:~$ cat my_msg.csv
AAA,--香蕉------,11111111
BBB,----------,22222222
CCC,----------,33333333
DDD,---苹果----,44444444
EEE,-----香蕉---,55555555
FFF,----------,66666666
⏹sed 的默认行为是在处理多个文件时,将它们视为一个连续的输入流来处理。
- 默认情况下sed命令会将两个文件
my_info.csv
,my_msg.csv
在内存中合成一个文件进行处理 - 所以通过
sed -n '1p'
来获取的时候,实际上是从内存中合成后的文件中进行读取,所以只能读取到第一行
同理,sed -n '$p'
也只能获取到最后一行。
fengyehong@ubuntu:~$ sed -n '/香蕉/p' my_info.csv my_msg.csv
111,--香蕉------,11111111
555,-----香蕉---,55555555
AAA,--香蕉------,11111111
EEE,-----香蕉---,55555555
# 尝试获取两个csv文件的第一行,却只获取到了第一个csv文件的第一行
fengyehong@ubuntu:~$ sed -n '1p' my_info.csv my_msg.csv
111,--香蕉------,11111111
fengyehong@ubuntu:~$
# 尝试获取两个csv文件的最后一行,却只获取到了第二个csv文件的最后一行
fengyehong@ubuntu:~$ sed -n '$p' my_info.csv my_msg.csv
FFF,----------,66666666
fengyehong@ubuntu:~$
⏹添加了-s
配置项之后,sed不会将两个文件视为一个输入流,而是视为两个输入流。
# 分别从两个文件中获取出了第一行
fengyehong@ubuntu:~$ sed -n -s '1p' my_info.csv my_msg.csv
111,--香蕉------,11111111
AAA,--香蕉------,11111111
fengyehong@ubuntu:~$
# 分别从两个文件中获取出了最后一行
fengyehong@ubuntu:~$ sed -n -s '$p' my_info.csv my_msg.csv
666,----------,66666666
FFF,----------,66666666
fengyehong@ubuntu:~$
三. 命令用法
3.1 s 字符串替换
sed 's/原字符串/新字符串/flag' 文件名
- 原字符串:支持字符串或正则表达式
- flag:用于控制替换行为
g
:全局替换p
:打印被替换的行i
:忽略大小写n
:指定替换第 n 个匹配项
⏹有文件如下所示
fengyehong@ubuntu:~$ cat my_info.csv
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
fengyehong@ubuntu:~$
3.1.1 g 标识符
⏹一行中有多个香蕉,由于没有使用g
标识符,所以只会替换每行的第一个
fengyehong@ubuntu:~$ sed 's/香蕉/banana/' my_info.csv
111,--banana--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----banana---,55555555
666,----------,66666666
⏹使用g
标识符之后的效果
- 注意:分割线并不一定非得是
/
,#
等其他符号也可以。
fengyehong@ubuntu:~$ sed 's#香蕉#banana#g' my_info.csv
111,--banana--banana----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----banana---,55555555
666,----------,66666666
3.1.2 p 标识符
⏹使用p
标识符,配合n
配置项,只打印被替换的行
fengyehong@ubuntu:~$ sed -n 's#苹果#apple#p' my_info.csv
444,---apple----,44444444
3.2 a 匹配行后追加
sed '命令地址a 新文本' 文件名
/匹配文本/a\追加文本
⏹有文件如下所示
fengyehong@ubuntu:~$ cat my_info.csv
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666----------,66666666fengyehong@ubuntu:~$
3.2.1 指定行后追加内容
2a
:2表示第2行;a表示append,追加
fengyehong@ubuntu:~$ sed '2a 我是在第2行之后新追加的内容' my_info.csv
111,--香蕉--香蕉----,11111111
222,----------,22222222
我是在第2行之后新追加的内容
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
3.2.2 包含指定内容的行后追加内容
fengyehong@ubuntu:~$ sed '/香蕉/a 我的上一行里面有香蕉' my_info.csv
111,--香蕉--香蕉----,11111111
我的上一行里面有香蕉
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
我的上一行里面有香蕉
666,----------,66666666
3.3 i 匹配行前追加
sed '命令地址i 新文本' 文件名
/匹配文本/i\追加文本
⏹有文件如下所示
fengyehong@ubuntu:~$ cat my_info.csv
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666----------,66666666fengyehong@ubuntu:~$
3.3.1 指定行前追加内容
2i
:2表示第2行;a表示insert,追加
fengyehong@ubuntu:~$ sed '2i 我是在第2行之前追加的内容' my_info.csv
111,--香蕉--香蕉----,11111111
我是在第2行之前追加的内容
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
3.3.2 包含指定内容的行后追加内容
fengyehong@ubuntu:~$ sed '/香蕉/i 我的下一行里面有香蕉' my_info.csv
我的下一行里面有香蕉
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
我的下一行里面有香蕉
555,-----香蕉---,55555555
666,----------,66666666
3.4 d 删除指定行
3.4.1 删除第2~4行
fengyehong@ubuntu:~$ sed '2,4d' my_info.csv
111,--香蕉--香蕉----,11111111
555,-----香蕉---,55555555
666,----------,66666666
3.4.2 删除第2和第4行
fengyehong@ubuntu:~$ sed '2d;4d' my_info.csv
111,--香蕉--香蕉----,11111111
333,----------,33333333
555,-----香蕉---,55555555
666,----------,66666666
3.4.3 删除包含香蕉的行
fengyehong@ubuntu:~$ sed '/香蕉/d' my_info.csv
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
666,----------,66666666
3.5 p 打印指定行
⏹打印第2和第4行
fengyehong@ubuntu:~$ sed -n '2p;4p' my_info.csv
222,----------,22222222
444,---苹果----,44444444
3.6 c 替换指定行
3.6.1 将第2行替换为指定的内容
fengyehong@ubuntu:~$ sed '2c 我是替换之后的第2行的内容' my_info.csv
111,--香蕉--香蕉----,11111111
我是替换之后的第2行的内容
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
3.6.2 将第2~4行替换为指定的内容
fengyehong@ubuntu:~$ sed '2,4c\我是替换之后的内容' my_info.csv
111,--香蕉--香蕉----,11111111
我是替换之后的内容
555,-----香蕉---,55555555
666,----------,66666666
3.6.3 将第2和第4行替换为指定的内容
fengyehong@ubuntu:~$ sed -e '2c 第2行的内容已经被我替换了' -e '4c 第4行的内容已经被我替换了' my_info.csv
111,--香蕉--香蕉----,11111111
第2行的内容已经被我替换了
333,----------,33333333
第4行的内容已经被我替换了
555,-----香蕉---,55555555
666,----------,66666666
3.6.4 将指包含内容给的行替换为指定的内容
fengyehong@ubuntu:~$ sed '/香蕉/c\***' my_info.csv
***
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
***
666,----------,66666666
3.7 r 读入指定文本
fengyehong@ubuntu:~$ cat my_info.csv
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
fengyehong@ubuntu:~$
fengyehong@ubuntu:~$ cat my_content.txt
你好
haha
AAA
VVV
3.7.1 读取A文件内容到B文件第一行之后
fengyehong@ubuntu:~$ sed '1r ./my_content.txt' my_info.csv
111,--香蕉--香蕉----,11111111
你好
haha
AAA
VVV
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
3.7.2 读取A文件内容到B文件最后一行之后
fengyehong@ubuntu:~$ sed '$r ./my_content.txt' my_info.csv
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
你好
haha
AAA
VVV
3.8 w 写入内容到指定文本
fengyehong@ubuntu:~$ cat my_info.csv
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
fengyehong@ubuntu:~$
fengyehong@ubuntu:~$ cat my_content.txt
你好
haha
AAA
VVV
3.8.1 将A文件的指定行内容写入到B文件中
⏹将my_info.csv
文件中的第1~3行的内容写入到my_content.txt
文件中,my_content.txt
文件原本的内容会被清除。
fengyehong@ubuntu:~$ sed '1,3w ./my_content.txt' my_info.csv
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
444,---苹果----,44444444
555,-----香蕉---,55555555
666,----------,66666666
fengyehong@ubuntu:~$
fengyehong@ubuntu:~$ cat my_content.txt
111,--香蕉--香蕉----,11111111
222,----------,22222222
333,----------,33333333
fengyehong@ubuntu:~$