Linux 用于处理文本数据的三剑客,分别为 grep 命令、awk 命令和 sed 命令,再加上正则表达式,就可以处理文本文件中各种常见的数据需求了。一般来说,grep 命令倾向于查找,sed 命令倾向于编辑更新,awk 命令则倾向于数据的分析和处理,本篇将重点梳理 sed 命令及常见的使用场景。
sed 是文本处理中非常好用的工具,能够完美的配合正则表达式,主要用来自动编辑一个或多个文件,可将数据进行替换、删除、新增、选取特定行等操作,从而简化对文件的反复操作,编写转换程序等。处理时,先把当前处理的行存储在临时缓冲区中(模式空间),接着用 sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后,处理下一行,这样不断重复,直到文件处理结束。
sed 命令的使用格式,如下:
sed [参数选项] 操作
-e:直接使用命令行模式进行 sed 相关的操作;
-n:表示操作使用安静模式,避免所有来自 stdin 的数据打印输出;
-r:表示操作使用的是扩展型正则表达式的语法;
-f:表示执行文件内的 sed 相关操作;
-i:表示直接修改读取的文件内容,而不输出打印;
-i.bak∶ 备份文件,并原处编辑修改
a:新增,比如 ‘xa 字符串’,表示在第 x 行的下一行,新增该字符串作为新的一行;
i:插入,比如 ‘xi 字符串’,表示在第 x 行的上一行,插入该字符串作为新的一行;
d:删除,比如 ‘xd’,表示删除第 x 行的数据;又比如 ‘x,yd’,表示删除第 x 行到第 y 行的数据;又比如 ‘x,$d’,表示删除第 x 行到最后一行的数据(美元符号表示最后的含义);
c:替换,比如 ‘xc 字符串’,表示用该字符串替换第 x 行的数据;又比如 ‘x,yc’,表示用该字符串替换第 x 行到第 y 行的数据;
p:查询,将选择的数据打印显示,通常和-n参数搭配使用,比如 sed -n ‘x,yp’,表示打印显示第 x 行到第 y 行的数据;
s:替换,直接替换匹配到的文本内容,通常和正则表达式搭配使用,比如 sed -i 's/原字符串/新字符串/g ',表示用新字符串替换所有的旧字符串;
w:写入,将原文件的内容或按条件匹配到的内容写到另一个目标文件中。
p:打印,打印出匹配的内容,通常与-n选项和用
w /path/filename :保存模式匹配的行至指定文件
r /path/filename:读取指定文件的文本内容至模式空间中
n :匹配它的下一行
= :为模式空间中的行打印行号
! :模式空间中匹配行取反处理
s/ / /:查找替换,支持使用其他分隔符,s@@@ , s###
替换标记:
g:行内全局替换
p:显示替换成功的行
w /path/to/filename:将替换成功的行保存至文本中
特殊字符:\n 表示换行
\t 表示tab
#删除某行
sed '1d' file #删除第一行
sed '$d' file #删除最后一行
sed '1,2d' file #删除第一行到第二行
sed '2,$d' file #删除第二行到最后一行
sed -i '/ruby/d' file #在原文件中删除ruby所在的行
#显示某行
sed -n '1p' file #显示第一行
sed -n '$p' file #显示最后一行
sed -n '1,2p' file #显示第一行到第二行
sed -n '2,$p' file #显示第二行到最后一行
sed -n '/ruby/d' file #显示删除ruby所在行的内容
#使用模式进行查询
sed -n '/ruby/p' file #查询包括关键字ruby所在所有行
sed -n '/\$/p' file #查询包括关键字$所在所有行,使用反斜线\屏蔽特殊含义
#增加一行或多行字符串
sed '1a drink tea' file #第一行后增加字符串"drink tea"
sed '1a\drink tea' file #第一行后增加字符串"drink tea"
sed '1,3a drink tea' file #第一行到第三行后增加字符串"drink tea"
sed '1a drink tea\nor coffee' file #第一行后增加多行,使用换行符\n
#代替一行或多行
sed '1c Hi' file #第一行代替为Hi
sed '1,2c Hi' file #第一行到第二行代替为Hi
sed '/ruby/c\python' #替换ruby所在的行为python
sed 's/.*ruby.*/python/g' #替换ruby所在的行为python
sed 's/[()]//g' "(127.0.0.1)" #将圆括号去掉
替换
#替换一行中的某部分
#格式:sed 's/要替换的字符串/新的字符串/g'(要替换的字符串可以用正则表达式)
sed 's/ruby/bird/g' file #替换ruby为bird
sed 's/ruby//g' file #替换ruby为空
#插入
sed -i '$a bye' file #在文件test1中最后一行直接输入"bye"
sed -i '1i\aaa' file #在文件test1中第一行前插入一行"aaa"
搞懂了 sed 命令的相关知识点后,可以动动手验证,并练习下常见的文本操作了,以 demo.txt 文件为例演示。
[xxw@localhost ~]$ cat demo.txt
hello
very nice
lalalala
11111111|22222222|333333?
44444444?|5555?5555|666666?
lalalala
today is nice
gogogogog
lalalala
yyds
<1>、在文件首行添加一行 “I want to fly” 字符串,使用 i 操作符(当前行的上一行)
[xxw@localhost ~]$ sed -i '1i I want to fly' demo.txt #1i:这个的一就是对第一行,i在前面输入
[xxw@localhost ~]$ cat demo.txt
I want to fly
hello
very nice
lalalala
(后面显示省略....)
[root@node01 ~]# sed '/hello/ijjyy' demo.txt #定位到hello这一行在上面添加
I want to fly
jjyy
hello
very nice
lalalala
11111111|22222222|333333?
44444444?|5555?5555|666666?
lalalala
today is nice
gogogogog
lalalala
yyds
注意:要想保存修改后的文件,需要使用重定向生成新的文件,或者直接修改源文件本身,则需要使用“-i”参数。
<2>、在文件最后一行添加一行 “process over” 字符串,使用 a 操作符(当前行的下一行)
[root@node01 ~]# sed '$a process over' demo.txt I want to fly
hello
very nice
lalalala
11111111|22222222|333333?
44444444?|5555?5555|666666?
lalalala
today is nice
gogogogog
lalalala
yyds
process over
<3>、在文件第5行的前后各添加一行,i就是在第5排加,a就是在第5排下面加
[root@node01 ~]# sed -i '5i AAAAAA' demo.txt
[root@node01 ~]# sed -i '5a bbbbbb' demo.txt
[root@node01 ~]# cat demo.txt
I want to fly
hello
very nice
AAAAAA
bbbbbb
lalalala
(后面显示省略....)
<4>、在文件第2行的后面添加3行数据(使用 \ 增加行数)
[xxw@localhost ~]$ sed -i '5i AAAAAAAAA' demo.txt
[xxw@localhost ~]$ sed -i '5a BBBBBBBBB' demo.txt
[xxw@localhost ~]$ cat demo.txt
I want to fly
hello
very nice
AAAAAAAAA
BBBBBBBBB
lalalala
(后面显示省略....)
[root@node01 ~]# sed -i '2a xxxx\nyyyy\nzzzz' demo.txt #写道一排也可以\n表示换行
[root@node01 ~]# cat demo.txt
I want to fly
hello
xxxx
yyyy
zzzz
xxxxxxxx
yyyyyyyyy
zzzzzzzzz
very nice
AAAAAA
bbbbbb
lalalala
<1>、删除第一行、最后一行、含指定字符串的行
[root@node01 ~]# cat demo.txt
I want to fly
hello
xxxx
yyyy
zzzz
xxxxxxxx
yyyyyyyyy
zzzzzzzzz
very nice
AAAAAA
bbbbbb
lalalala
11111111|22222222|333333?
44444444?|5555?5555|666666?
lalalala
today is nice
gogogogog
lalalala
yyds
[root@node01 ~]# sed -i '1d' demo.txt #删除第一行
[root@node01 ~]# sed -i '$d' demo.txt #删除最后一行
[root@node01 ~]# cat demo.txt
hello
xxxx
yyyy
zzzz
xxxxxxxx
yyyyyyyyy
zzzzzzzzz
very nice
AAAAAA
bbbbbb
lalalala
11111111|22222222|333333?
44444444?|5555?5555|666666?
lalalala
today is nice
gogogogog
lalalala
<2>、删除第2行~第4行的数据
[xxw@localhost ~]$ sed -i '2,4d' demo.txt
[xxw@localhost ~]$ cat demo.txt
hello
very nice
AAAAAAAAA
(中间显示省略....)
lalalala
yyds
<3>、删除空白行
[xxw@localhost ~]$ sed -i '/^$/d' demo.txt
[xxw@localhost ~]$ cat demo.txt
hello
very nice
AAAAAAAAA
BBBBBBBBB
lalalala
(中间显示省略....)
lalalala
yyds
<4>、删除每一行的指定字符(比如删除 nice 字符串)
[xxw@localhost ~]$ sed -i 's/nice//g' demo.txt
[xxw@localhost ~]$ cat demo.txt
hello
very
AAAAAAAAA
BBBBBBBBB
lalalala
(中间显示省略....)
today is
gogogogog
lalalala
yyds
#定位到有very的这一行,对nice进行替换,替换为空
[root@node01 ~]# sed '/very/s/nice//' demo.txt
hello
xxxxxxxx
yyyyyyyyy
zzzzzzzzz
very
AAAAAA
bbbbbb
lalalala
11111111|22222222|333333?
44444444?|5555?5555|666666?
<1>、把第2行~第4行替换成字符串"666666"(操作符 c 用于整行替换)
[xxw@localhost ~]$ sed -i '2,4c 666666' demo.txt
[xxw@localhost ~]$ cat demo.txt
hello
666666
lalalala
(中间显示省略....)
today is
gogogogog
lalalala
yyds
<2>、把文本中的所有小写字母a转成大写A
[xxw@localhost ~]$ sed -i 's/a/A/g' demo.txt
[xxw@localhost ~]$ cat demo.txt
hello
666666
lAlAlAlA
(中间显示省略....)
todAy is
gogogogog
lAlAlAlA
yyds
注意:‘s/旧字符串/新字符串/g’ 把文本中匹配到的所有旧字符串替换成新的字符串,请注意,操作符 g 表示会匹配每一行的所有字符串。
==> 如果只需要匹配每一行的第3个符合条件的字符串并替换,把 g 换成 3 即可:(方便演示,这里不再添加 -i 参数修改文本)
[xxw@localhost ~]$ sed 's/a/A/3' demo.txt
hello
666666
lalalAla
(中间显示省略....)
today is
gogogogog
lalalAla
yyds
==> 如果在 行首 或 行末尾 或 指定行范围 插入指定字符串:(方便演示,这里不再添加 -i 参数修改文本)
# 在每行行首插入指定字符串012U
[xxw@localhost ~]$ sed 's/^/012U/' demo.txt
012Uhello
012U666666
012Ulalalala
(中间显示省略....)
012Utoday is
012Ugogogogog
012Ulalalala
012Uyyds
# 在每行行末尾插入指定字符串012U
[xxw@localhost ~]$ sed 's/$/012U/' demo.txt
hello012U
666666012U
lalalala12U
(中间显示省略....)
today is 012U
gogogogog012U
lalalala012U
yyds012U
# 在第2行~第3行的行末尾插入指定字符串012U
[xxw@localhost ~]$ sed '2,3s/$/012U/' demo.txt
hello
666666012U
lalalala012U
(中间显示省略....)
today is
gogogogog
lalalala
yyds
# 在第2行~第3行的行首插入指定字符串012U
[xxw@localhost ~]$ sed '2,3s/^/012U/' demo.txt
hello
012Uxxxxxxxx
012Uyyyyyyyyy
zzzzzzzzz
very nice
aaaaaa
bbbbbb
==> 另外,如果把A字符改成空字符,则表示删除所有的a字符:(方便演示,这里不再添加 -i 参数修改文本)
[xxw@localhost ~]$ sed 's/a//g' demo.txt
hello
666666
llll
(中间显示省略....)
tody is
gogogogog
llll
yyds
<3>、把文本中的每一行末尾的?,替换成!
[xxw@localhost ~]$ sed -i 's/\?$/\!/g' demo.txt
11111111|22222222|333333!
44444444?|5555?5555|666666!
<4>将所有大写字母转换为小写字母:
sed 's/[A-Z]/\L&/g' filename
<5>将所有小写字母转换为大写字母:
sed 's/[a-z]/\U&/g' filename
<6>将文本中的首字母转换为大写:
sed 's/\b\([a-z]\)/\u\1/g' filename
<7>将文本中的首字母转换为小写:
sed 's/\b\([A-Z]\)/\l\1/g' filename
<8>定位到最后一行中的qqq把中间的zzz替换为dxw
/[要定位的行的内容]/s/[匹配的内容]/[需要替换的内容]/g
[root@node01 ~]# cat demo.txt
....省略....
11111111|22222222|333333!
44444444!|5555!5555|666666!
today is
gogogogog
qqqzzzwww
[root@node01 ~]# sed '/qqq/s/zzz/dxw/g' demo.txt
....省略....
today is
gogogogog
qqqdxwwww
完成!!!
<9> 将第一行和第二行合并为一行
?N #这里的问号写第几行就是合并它下一行和它自己本身
[root@node01 ~]# cat demo.txt
123456
hello
xxxxxxxx
yyyyyyyyy
....省略....
[root@node01 ~]# sed '1N;s/\n//' demo.txt #把第一行和第二行合并
123456hello
xxxxxxxx
yyyyyyyyy
zzzzzzzzz
<10>要使用sed
中的y
命令来替换文本中的小写字母为大写字母,你可以使用以下方法:
假设有一个文本文件text.txt
,其中包含小写字母的内容。你可以使用以下命令将小写字母替换为对应的大写字母:
sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' text.txt
请替换命令中的filename
为你想要操作的文件名或者使用管道符号|
将命令连接到其他命令输出。
<11>把文中的第二个tab替换为换行
\n 换行
\t tab
[root@kh2 ~]# cat abc
255.255.255.0
144.144. 144. 144
jjyy
123456
123456
[root@kh2 ~]# sed 's/\t/\n/2' abc
255.255.255.0
144.144. 144.
144
jjyy
123456
123456
<12>二次替换,在上一次替换前面加上;就是在前面替换的结果继续处理
[root@kh2 ~]# cat erchi
.Ah "Major Heading"
[root@kh2 ~]# sed '/.Ah/s/.Ah/@A HEAD =/;s/"//g' erchi
@A HEAD = Major Heading
<13>&是一个特殊字符,用于表示与之前找到的模式匹配的内容。它可以在替换操作中使用,将模式匹配的内容插入到替换字符串中。
1.
echo "Hello, world!" | sed 's/world/(&)/'
Hello, (world)!
2.
[root@kh2 ~]# cat abc
on the UNIX Operat ing System.
[root@kh2 ~]# sed 's/UNIX/\\s-2&\\sO/g' abc #匹配我查找到的内容
on the \s-2UNIX\sO Operat ing System.
[root@kh2 ~]# sed 's/UNIX/\\s-2UNIX\\sO/g' abc
on the \s-2UNIX\sO Operat ing System.
3.在匹配到的内容用括号括起来,我们这边用到了正则表达式所以要带-r
[root@kh2 ~]# cat abc
on the UNIX Operat ing System.
See Section 1.4
See Section 12.9
(See Section 12.9)
[root@kh2 ~]# sed -r 's/See Section [1-9][0-9]?\.[1-9]?/(&)/g' abc
on the UNIX Operat ing System.
(See Section 1.4)
(See Section 12.9)
((See Section 12.9))
<14>位置替换
\1
:引用第一个捕获组的内容。\2
:引用第二个捕获组的内容。\3
引用第三个捕获组的内容,以此类推。[root@kh2 ~]# cat abc
dxw:dzy
jjyy:qqzz
[root@kh2 ~]# sed -r 's/(.*):(.*)/\2:\1/g' abc
dzy:dxw
qqzz:jjyy
<15>提取"""的内容
第一步先匹配哪一行打印,在删除.Ah和""
[root@kh2 ~]# cat b
.Ah "Comment"
.Ah "Substitution"
.Ah "Delete"
.Ah "Append,Insert and Change"
.Ah "List"
[root@kh2 ~]# sed '/^.Ah/{p;s/\.Ah //g;s/"//g}' b
.Ah "Comment"
Comment
.Ah "Substitution"
Substitution
.Ah "Delete"
Delete
.Ah "Append,Insert and Change"
Append,Insert and Change
.Ah "List"
List
<16> =显示匹配的内容在第几行
[root@kh2 ~]# sed '/.Ah/=' b
1
.Ah "Comment"
Comment
3
.Ah "Substitution"
Substitution
5
.Ah "Delete"
<17>n 匹配它的下一行,然后下一行是空行就删除
[root@kh2 ~]# cat b
.Ah "Comment"
Comment
.Ah "Substitution"
[root@kh2 ~]# sed '/^.Ah/{n;/^$/d}' b 成功删除
.Ah "Comment"
Comment
.Ah "Substitution"
Substitution
<1>、查找第3行到第5行内容(操作符 p 不搭配 -n 使用,则会重复输出第3行到第5行内容)
xxw@localhost ~]$ sed -n '3,5p' demo.txt
lAlAlAlA
11111111|22222222|333333!
44444444?|5555?5555|666666!
<2>、分别查找偶数行和奇数行的内容
# 查找偶数行
[xxw@localhost ~]$ sed -n 'n;p' demo.txt
666666
11111111|22222222|333333!
lAlAlAlA
gogogogog
yyds
# 查找奇数行
[xxw@localhost ~]$ sed -n 'p;n' demo.txt
hello
lAlAlAlA
44444444?|5555?5555|666666!
todAy is
lAlAlAlA
注意:查找偶数行和奇数行,也可以使用这种方式:
# 查找偶数行
[xxw@localhost ~]$ sed -n '2~2p' demo.txt
# 查找奇数行
[xxw@localhost ~]$ sed -n '1~2p' demo.txt
<3>、查找有特定字符串的行内容
# 查找含有"lAlA"字符串的所有行
[xxw@localhost ~]$ sed -n '/lAlA/p' demo.txt
lAlAlAlA
lAlAlAlA
lAlAlAlA
# 查找包含指定单词的行,\<单词\>表示单词边界
[xxw@localhost ~]$ sed -n '/\/p' demo.txt
todAy is
# 查找以wei字符串开头的行
[xxw@localhost ~]$ sed -n '/^wei/p' demo.txt
# 查找以xiang字符串结尾的行
[xxw@localhost ~]$ sed -n '/.xiang/p' demo.txt
# 查找以数字结尾的行
[xxw@localhost ~]$ sed -n '/[0-9]$/p' demo.txt
666666
11111111|22222222|333333!
44444444?|5555?5555|666666!
使用 -e 参数,可以在同一行里执行多条命令。比如,先在每行的行首添加 012U 字符串,再在最后一行添加 “I like you” 字符串。
[xxw@localhost ~]$ sed -e 's/^/012U/' -e '$a I like you' demo.txt
012Uhello
012U666666
012UlAlAlAlA
(中间显示省略....)
012UtodAy is
012Ugogogogog
012UlAlAlAlA
012Uyyds
I like you
请注意,多条命令是按顺序执行的,不同的顺序将产生不同的结果,如果把第二个命令放在最前面,则 “I like you” 字符串会变成 “012UI like you” 。当然,-e 参数也可以换成 --expression 。
使用操作符 w 可以备份原文件的内容到另一个文件。比如,把 demo.txt 文件内容全部备份到 demo1.txt。
[xxw@localhost ~]$ sed 'w demo1.txt' demo.txt
hello
666666
lAlAlAlA
(中间显示省略....)
todAy is
gogogogog
lAlAlAlA
yyds
# 如果不想打印备份时屏幕输出的这些内容,可以使用-n参数
[xxw@localhost ~]$ sed -n 'w demo1.txt' demo.txt
[xxw@localhost ~]$ cat demo1.txt
hello
666666
lAlAlAlA
(中间显示省略....)
todAy is
gogogogog
lAlAlAlA
yyds
还有一种情况,如果我只需要备份符合条件的行数据到另一个文件,那可以使用正则表达式匹配:
# 把数字开头的行数据,备份到demo2.txt文件
[xxw@localhost ~]$ sed -n '/^[0-9]/w demo2.txt' demo.txt
[xxw@localhost ~]$ cat demo2.txt
666666
11111111|22222222|333333!
44444444?|5555?5555|666666!
以上是 sed 命令常见的使用场景,结合正则表达式,它还能处理更为复杂的场景,以下是 sed 命令常用的正则表达式匹配:
本篇重点梳理了 sed 命令的用法,并对常见使用场景进行演示,sed 作为一种文本编辑的强大工具,通常需要搭配正则表达式使用,才能完美的处理更为复杂的需求。另外,sed 本身也是一个管道命令,也可以与 grep、awk 等常见的命令搭配使用,它常被用在 shell 脚本的编写,值得我们去学习和掌握。
原文链接:https://blog.csdn.net/qq_29119581/article/details/125670550
n ‘w demo1.txt’ demo.txt
[xxw@localhost ~]$ cat demo1.txt
hello
666666
lAlAlAlA
(中间显示省略…)
todAy is
gogogogog
lAlAlAlA
yyds
还有一种情况,如果我只需要备份符合条件的行数据到另一个文件,那可以使用[正则表达式匹配](https://so.csdn.net/so/search?q=正则表达式匹配&spm=1001.2101.3001.7020):
[xxw@localhost ~]$ sed -n ‘/1/w demo2.txt’ demo.txt
[xxw@localhost ~]$ cat demo2.txt
666666
11111111|22222222|333333!
44444444?|5555?5555|666666!
以上是 sed 命令常见的使用场景,结合正则表达式,它还能处理更为复杂的场景,以下是 sed 命令常用的正则表达式匹配:
[外链图片转存中...(img-9KUojTPR-1696408452928)]
## 最后
本篇重点梳理了 sed 命令的用法,并对常见使用场景进行演示,sed 作为一种文本编辑的强大工具,通常需要搭配正则表达式使用,才能完美的处理更为复杂的需求。另外,sed 本身也是一个管道命令,也可以与 grep、awk 等常见的命令搭配使用,它常被用在 shell 脚本的编写,值得我们去学习和掌握。
原文链接:https://blog.csdn.net/qq_29119581/article/details/125670550
原文链接:https://blog.csdn.net/d1240673769/article/details/103723838
0-9 ↩︎