文本三剑客:都是按行读取后处理。
- grep 过滤行内容。
- awk 过滤字段。
- sed 过滤行内容;修改行内容。
sed编辑器
sed(意为流编辑器,“stream editor”的缩写)是一个使用简单紧凑的编程语言来解析和转换文本[Unix]实用程序。虽然在某些方面类似于允许脚本编辑的编辑器,但只需对输入进行一次传递即可工作,因此效率更高。但是,它能够过滤管道中的文本,这特别将其与其他类型的编辑器区分开来。
sed的工作过程
sed的工作流程主要包括读取、执行和显示三个过程:
- 读取: sed从输入流 (文件、管道、标准输入) 中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space )。
- 执行: 默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行。
- 显示: 发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行, 直至所有内容被处理完。
在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。
注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非使用"sed -i"修改源文件、或使用重定向输出到新的文件中。
sed命令格式
命令格式:
sed -e '操作' 文件1 文件2
sed -n -e '操作' 文件1 文件2
sed -f 脚本文件 文件1 文件2
sed -i -e '操作' 文件1 文件2
执行多条命令的格式:
sed -n -e '操作1' -e '操作2' 文件
sed -n -e '操作1;操作2' 文件
sed -e 'n{
操作1
操作2
}' 文件1
选项:
| 选项 | 作用 |
|---|---|
| -e 或--expression= | 表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用 |
| -f 或--file= | 表示用指定的脚本文件来处理输入的文本文件 |
| -h 或--help | 显示帮助 |
| -n、--quiet或--silent | 禁止sed编辑器输出,但可以与p命令一起使用完成输出 |
| -i | 直接修改目标文本文件 |
常用操作:
| 操作 | 作用 |
|---|---|
| s | 替换,替换指定字符 |
| d | 删除,删除选定的行 |
| a | 增加,在当前行下方增加一行指定内容 |
| i | 插入,在选定行上方插入一行指定内容 |
| c | 替换,将选定行替换为指定内容 |
| y | 字符转换,转换前后的字符长度必须相同 |
| p | 打印行内容。如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以ASCII码输出。其通常与"-n"选项一起使用 |
| = | 打印行号 |
| l | (小写L)打印数据流中的文本和不可打印的ASCII字符(比如结束符$、制表符\t) |
sed最常用功能:增删改查(可配正则表达式)
增:i(在行前插入内容)、a(在行后添加内容)、r(在行后读入文件的内容)
删:d
改:s(字符串替换)、c(整行替换)、y(对应字符进行替换,效果类似tr命令)
查:p
复制粘贴:H(复制)G(粘贴到指定行下方)
增
i:在行前插入内容
a:在行后加入内容
r:在行后读入文件内容
在行前插入内容 i
sed '1i 11' sed.txt
11
one
two
three
four
five
six
seven
eight
nine
ten
sed '1,3i 123' sed.txt
123
one
123
two
123
three
four
five
six
seven
eight
nine
ten
在行后加入内容 a
sed '1a 123' sed.txt
one
123
two
three
four
five
six
seven
eight
nine
ten
sed '$a 123' sed.txt
one
two
three
four
five
six
seven
eight
nine
ten
123
sed '1a 22\n33\n44' sed.txt
one
22
33
44
two
three
four
five
six
seven
eight
nine
ten
在行后添加文件内容 r
cat aa.txt
hello world
sed '5r aa.txt' sed.txt
one
two
three
four
five
hello world
six
seven
eight
nine
ten
删
[root@localhost ~]#sed '3d' sed.txt
one
two
four
five
six
seven
eight
nine
ten
[root@localhost ~]#sed '1,9d' sed.txt
ten
[root@localhost ~]#sed '$d' sed.txt
one
two
three
four
five
six
seven
eight
nine
[root@localhost ~]#sed 'd' sed.txt
[root@localhost ~]#
[root@localhost ~]#sed '1,+3d' sed.txt
five
six
seven
eight
nine
ten
[root@localhost ~]#sed '6,$d' sed.txt
one
two
three
four
five
[root@localhost ~]#sed '6!d' sed.txt
six
[root@localhost ~]#sed '6,$!d' sed.txt
six
seven
eight
nine
ten
[root@localhost ~]#
通过字符串匹配出想要的行
[root@localhost ~]#sed '/e$/d' sed.txt
two
four
six
seven
eight
ten
[root@localhost ~]#sed '/e$/!d' sed.txt
one
three
five
nine
[root@localhost ~]#
删除空行
cat aa.txt
1
2
3
4
sed -i '/^$/d' aa.txt
cat aa.txt
1
2
3
4
删除空行的三种方法:
1.grep -v "^$" 文件 ##过滤出非空行
2.cat 文件 |tr -s "\n" ##压缩换行符
3.sed '/^$/d' 文件 ##删除空行
改
s:替换字符串
c:整行替换
y:字符替换,替换前后的字符串长度必须相同
替换字符串 s
格式:
行范围 s/旧字符串/新字符串/替换标记
4种替换标记:
数字:表明新字符串将替换第几处匹配的地方
g:表面新字符串将会替换所有匹配的地方
p:打印与替换命令匹配的行,与-n一起使用
w 文件:将替换的结果写入文件中
示例:
在过滤的行中替换root
sed -n '/root/p' gai.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
sed -n 's/root/abc/p' gai.txt
abc:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/abc:/sbin/nologin
sed -n 's/root/abc/2p' gai.txt
root:x:0:0:abc:/root:/bin/bash
sed -n 's/root/abc/3p' gai.txt
root:x:0:0:root:/abc:/bin/bash
sed -n 's/root/abc/gp' gai.txt
abc:x:0:0:abc:/abc:/bin/bash
operator:x:11:0:operator:/abc:/sbin/nologin
删除行中的root(就是将root更换为空)
sed -n 's/root//gp' gai.txt
:x:0:0::/:/bin/bash
operator:x:11:0:operator:/:/sbin/nologin
echo 000010101 | sed 's/^0*//'
10101
在行首加入注释#
sed -n '/^root/p' gai.txt
root:x:0:0:root:/root:/bin/bash
sed -n '/^root/ s/^/#/p' gai.txt
#root:x:0:0:root:/root:/bin/bash
sed -n '/root/ s/$/#/p' gai.txt
root:x:0:0:root:/root:/bin/bash#
operator:x:11:0:operator:/root:/sbin/nologin#
使用脚本来进行多条操作的更改
-f可以使用指定的脚本来进行操作
sed -n -f shiyan.sh gai.txt
#root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/sbin/nologin#
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin#
#operator:x:11:0:operator:/root:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin#
cat shiyan.sh
/root/ s/^/#/p
3,5 s/$/#/p
将修改后的内容保存到另一个文件中
使用重定向更改并保存
cat sed.txt
one
two
three
four
five
six
seven
eight
nine
ten
sed '1,5 s/^/#/' sed.txt>sed1.txt
cat sed1.txt
#one
#two
#three
#four
#five
six
seven
eight
nine
ten
sed -n '1,5 s/^/#/p' sed.txt>sed1.txt
cat sed1.txt
#one
#two
#three
#four
#five
整行替换 c
用字符c可以将匹配的字符全部替换为设置的字符
将包含字符串fo的行,整体替换成22。
sed '/e/c 123' sed.txt
123
two
123
four
123
six
123
123
123
123
cat sed.txt
one
two
three
four
five
six
seven
eight
nine
ten
单字符替换 y
可以将匹配的单个字符进行替换
遇到n替换成2,遇到o替换成5。
sed 'y/tf/54/' sed.txt
one
5wo
5hree
4our
4ive
six
seven
eigh5
nine
5en
查
sed编辑器默认输出行内容,-n选项可以禁止输出。如果不加-n,却使用p操作,那么每行内容会打印两次。
sed -e "p" :每行内容打印两次。
sed -n "p" :每行内容只打印一次。
sed -e 'p' sed.txt
one
one
two
two
three
three
four
four
five
five
six
six
seven
seven
eight
eight
nine
nine
ten
ten
sed -n -e 'p' sed.txt
one
two
three
four
five
six
seven
eight
nine
ten
打印行号
sed -e '=' sed.txt
1
one
2
two
3
three
4
four
5
five
6
six
7
seven
8
eight
9
nine
10
ten
sed -n '=' sed.txt
1
2
3
4
5
6
7
8
9
10
sed 对指定行进行操作
两种方法:
- 以数字形式表示行区间;
- 用文本模式(字符串)来过滤出行(一般结合正则表达式)。 以数字形式表示行区间:
| 操作 | 含义 |
|---|---|
| '1p' | 打印第一行 |
| '$p' | 打印最后一行 |
| '1,3p' | 打印连续行,打印第一行到第三行 |
| '6,$p' | 打印第六行到最后一行 |
| '1,+3p' | 打印第一行加后面三行(即打印第一到第四行) |
| '5q' | 打印前五行后退出 |
| 'p;n' | 打印奇数行 |
| 'n;p' | 打印偶数行 |
使用字符串匹配出行:
| 操作 | 含义 |
|---|---|
| '/root/p' | 打印包含root的行 |
| '/root/!p' | 打印不包含root的行。! 表示取反 |
| '/^root/p' | 打印以root开头的行 |
| '/bash$/' | 打印以bash结尾的行 |
| '/root l bash/p' | 打印包含root或bash的行。"l"是扩展正则表达式的元字符,要使用sed -r |
| '6,/root/p' | 打印第6行到第一个包含root的行 |
以数字形式表示行区间
sed -n '1p' sed.txt
one
sed -n '$p' sed.txt
ten
sed -n -e '1p' -e '5p' sed.txt
one
five
连续打印
使用,可以连续打印
sed -n '1,5p' sed.txt
one
two
three
four
five
使用sed打印奇数行或者偶数行
sed -n 'p;n' sed.txt
one
three
five
seven
nine
sed -n 'n;p' sed.txt
two
four
six
eight
ten
使用正则表达式,匹配行内容
注意:sed 使用扩展正则表达式时,要加 -r
sed -n '/bash$/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
ky21:x:1000:1000:ky21:/home/ky21:/bin/bash
[root@192 ~]#sed -n '/^root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@192 ~]#sed -n '/root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
sed的复制粘贴
#sed命令: H复制、d删除、G粘贴到指定行下方
复制粘贴
sed '1,3 H;;$G' sed.txt
one
two
three
four
five
six
seven
eight
nine
ten
one
two
three