Linux文本处理三剑客之sed命令

Linux文本处理三剑客之sed命令

Linux 用于处理文本数据的三剑客,分别为 grep 命令、awk 命令和 sed 命令,再加上正则表达式,就可以处理文本文件中各种常见的数据需求了。一般来说,grep 命令倾向于查找,sed 命令倾向于编辑更新,awk 命令则倾向于数据的分析和处理,本篇将重点梳理 sed 命令及常见的使用场景。

一、sed 简介

sed 是文本处理中非常好用的工具,能够完美的配合正则表达式,主要用来自动编辑一个或多个文件,可将数据进行替换、删除、新增、选取特定行等操作,从而简化对文件的反复操作,编写转换程序等。处理时,先把当前处理的行存储在临时缓冲区中(模式空间),接着用 sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。然后,处理下一行,这样不断重复,直到文件处理结束。

sed 命令的使用格式,如下:

sed [参数选项] 操作

参数选项有:

-e:直接使用命令行模式进行 sed 相关的操作;
-n:表示操作使用安静模式,避免所有来自 stdin 的数据打印输出;
-r:表示操作使用的是扩展型正则表达式的语法;
-f:表示执行文件内的 sed 相关操作;
-i:表示直接修改读取的文件内容,而不输出打印;

-i.bak∶ 备份文件,并原处编辑修改

操作行为有:(为了描述方便,使用 x,y 表示数字)

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

命令示例:(假设我们有一文件名为file)

#删除某行
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 常见的操作,及其演示

搞懂了 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、新增操作

<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

2、删除操作

<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?

3、修改/替换操作

<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. \1:引用第一个捕获组的内容。
  2. \2:引用第二个捕获组的内容。
  3. 以此类推,\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

4、查询操作

<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!

5、多点编辑操作

使用 -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 。

6、文件备份

使用操作符 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 命令常用的正则表达式匹配:
Linux文本处理三剑客之sed命令_第1张图片

最后

本篇重点梳理了 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):

把数字开头的行数据,备份到demo2.txt文件

[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

  1. 0-9 ↩︎

你可能感兴趣的:(linux,运维,服务器)