From 68dcc3fb25f1ef8c036a1993485ff34ae7ad1018 Mon Sep 17 00:00:00 2001
From: wxin <15253413025@163.com>
Date: Sun, 30 Mar 2025 13:45:38 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20shell-sed.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
shell-sed.md | 674 +++++++++++++++++++++++++--------------------------
1 file changed, 337 insertions(+), 337 deletions(-)
diff --git a/shell-sed.md b/shell-sed.md
index 2da7dde..8820cf3 100644
--- a/shell-sed.md
+++ b/shell-sed.md
@@ -1,337 +1,337 @@
-
Shell Sed编译器
-
-------
-
-## 一:非交互式编译器 sed
-
-### 1. sed 介绍
-
- Linux 中,常使用流编辑器`Sed`进行文本替换工作。与交互式编辑器(如vim)不同,`Sed`编辑器以批处理的方式来编辑文件,这比交互式编辑器快得多,可以快速完成对数据的编辑修改。`Sed`编辑器会执行以下操作:
-
-- 一次从输入中读取一行数据;
-- 根据所提供的编辑器命令匹配数据;
-- 按照命令修改流中的数据;
-- 将新的数据输出到`STDOUT`。
-
- 在 Sed 编辑器匹配完一行数据后,它会读取下一行数据并重复这个过程,直到处理完所有数据。使用 Sed 命令打开一个 Sed 编辑器。
-
-
-
- `sed`是一种在线的、非交互式的编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(`pattern space`),接着用`sed`命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。`Sed`主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
-
-### 2. 语法格式
-
-```shell
-sed [options] 'command' file
-```
-
-**options【选项】**
-
-| 选项 | 作用 |
-| :--: | :----------------------------------------------------------: |
-| `-n` | 只有经过sed处理的行才会被列出 |
-| `-e` | 允许多点编辑 |
-| `-f` | 将sed的动作写在一个文本内,-f filename 则可以执行filename内的sed动作。 |
-| `-r` | 支持扩展正则 |
-| `-i` | 直接修改源文件 |
-
-**command【子命令】**
-
-| 子命令 | 作用 |
-| :----: | :------------------------------------------: |
-| `a` | 在指定行**之后**追加文本 |
-| `i` | 在指定行**之前**插入文本 |
-| `c` | 替换整行内容 |
-| `d` | 删除指定行 |
-| `w` | 将匹配行的内容写入外部文件 |
-| `y` | 按字符一一映射替换 |
-| `p` | 打印匹配的行(通常与 `-n` 静默模式结合使用) |
-| `r` | 从外部文件读取内容并插入到指定行后 |
-| `q` | 匹配到指定行后立即退出处理 |
-| `=` | 输出行号(行号单独显示,原行内容不变) |
-| `s` | 替换匹配的文本 |
-| `!` | 对匹配条件取反 |
-| `g` | 在 `s` 命令中替换所有匹配项 |
-| `数字` | 指定行号或范围 |
-
-**特殊子命令**
-
-| 子命令 | 作用 |
-| :----: | :------------------------------------: |
-| `h` | 将模式空间内容**覆盖**到保持空间 |
-| `H` | 将模式空间内容**追加**到保持空间 |
-| `g` | 用保持空间内容**覆盖**模式空间 |
-| `G` | 将保持空间内容**追加**到模式空间 |
-| `x` | 交换两个空间的内容 |
-| `n` | 读取下一行覆盖当前模式空间 |
-| `N` | 追加下一行到当前模式空间(合并多行) |
-| `P` | 打印多行模式空间的第一行 |
-| `D` | 删除多行模式空间的第一行并重新开始循环 |
-
-### 3. 定址
-
- 默认`sed`对文件中的所有行进行编辑。当然,也可以只指定特定的某些行,或者行范围进行流编辑,这需要用到行寻址。所指定的行地址放在子命令之前
-
-```shell
-[address]command
-```
-
-**数字定址**
-
- `sed`编辑器将文本流中的每一行都进行编号,第一行的编号为 1 ,后面的按顺序分配行号。通过指定特定的行号,可以选择编辑特定的行。
-
-```bash
-# 将第3行中所有的 bin 替换成 BIN
-[root@wxin ~]# sed '3 s/bin/BIN/g' /etc/passwd
-
-# 将第2到5行中所有的 bin 替换成 BIN
-[root@wxin ~]# sed '2,5 s/bin/BIN/g' /etc/passwd
-
-# 将第10行到最后一行中所有的 bin 替换成 BIN
-[root@wxin ~]# sed '10,$ s/bin/BIN/g' /etc/passwd
-```
-
-**正则定址**
-
- `sed`编辑器允许使用正则过滤出命令要作用的行
-
-```shell
-/pattern/command
-```
-
- 必须使用" / " 将要指定的 pattern 包起来。sed 会寻找匹配文本模式的行,然后对这些行执行编辑命令
-
-```bash
-[root@wxin ~]# sed -n '/root/s/bin/BIN/p' /etc/passwd
-
-# 寻找包含有字符串 root 的行,并将匹配行的 bin 替换为 BIN
-```
-
- 与数字寻址一样,也可以使用正则过滤区间来过滤行。
-
-```bash
-[root@wxin ~]# sed '/pattern1/,/pattern2/ edit_command' file
-```
-
- 这行命令会在文件 file 中先寻找匹配 pattern1 的行,然后从该行开始,执行编辑命令,直到找到匹配 pattern2 的行。但是需要注意的是,使用文本区间过滤文本时,只要匹配到了开始模式(pattern1),编辑命令就会开始执行,直到匹配到结束模式(pattern2),这会导致一种情况:一个文本中,先匹配到了一对 pattern1、pattern2,对该文本区间中的文本执行了编辑命令;然后,在 pattern2 之后又匹配到了 pattern1,这时就会再次开始执行编辑命令,因此,在使用文本区间过滤时要注意这一点。
-
-```bash
-[root@wxin ~]# sed -n '/root/,/nologin/ s/bin/BIN/p' /etc/passwd
-root:x:0:0:root:/root:/BIN/bash
-BIN:x:1:1:bin:/bin:/sbin/nologin
-operator:x:11:0:operator:/root:/sBIN/nologin
-games:x:12:100:games:/usr/games:/sBIN/nologin
-```
-
-### 4. 示例
-
-**`s`替换**
-
-使用`s`命令来进行文本替换
-
-```bash
-[root@wxin ~]# sed 's/srcStr/dstStr/' file
-```
-
- 其中,`srcStr`为想要替换的文本,`dstStr`为将要替换成的文本。使用`s`命令时,`sed`编辑器会在一行一行地读取文件`file`,并在每行查找文本`srcStr`,如果找到了,则将该处的`srcStr`替换为`dstStr`。
-
- `/`字符为界定符,用于分隔字符串(`sed`编辑器允许使用其他字符作为替换命令中的字符串分隔符):
-
-```bash
-[root@wxin ~]# sed 's!/bin/bash!/BIN/BASH!' /etc/passwd # 使用 ! 作为字符串分隔符
-[root@wxin ~]# sed 's#3#88#g' datafile
-```
-
- 默认,`s`只会替换掉目标文本在每行中第一次出现的地方。若想要替换掉每行中所有匹配的地方,可以使用替换标记`g`。替换标记放在编辑命令的末尾。除了`g`外,还有几种替换标记:
-
-1. 数字指明替换掉第几次匹配到的文本
-
- 没有设置这个标记时,默认是替换第一次匹配的文本
-
- ```bash
- [root@wxin ~]# sed 's/root/ROOT/2' /etc/passwd
- ```
-
- 这行命令将`/etc/passwd`文件中每行的第`2`个`root`替换为`ROOT`
-
-2. g 替换所有匹配到的文本
-
- ```bash
- [root@wxin ~]# sed 's/root/ROOT/g' /etc/passwd
- ```
-
- 这行命令将`/etc/passwd`文件中的`root`,全部替换为`ROOT`;
-
-3. p 打印与替换命令中指定模式(srcStr)相匹配的行
-
- ```bash
- [root@wxin ~]# sed 's/root/ROOT/p' /etc/passwd
- ```
-
- 执行这命令,会在 STDOUT 上看到包含有 root 的行被输出了两次,一次是 sed 编辑器自动输出的;另一次则是 p 标记打印出来的匹配行
-
- ```bash
- [root@wxin ~]# sed -n 's/root/ROOT/gp' /etc/passwd # 将 /etc/passwd 中所有的 root 都替换成 ROOT,并输出被修改的行
- ```
-
-**`d`删除**
-
- `sed`编辑器使用`d`命令来删除文本流中的特定行。使用`d`命令时,一般需要带上位寻址,以删除指定的行,否则默认会删除所有文本行。
-
-```bash
-[root@wxin ~]# sed '/root/d' /etc/passwd # 删除匹配 root 的行
-
-[root@wxin ~]# sed '2,$d' /etc/passwd # 删除第2到最后一行
-
-[root@wxin ~]# sed '3d' /etc/passwd
-[root@wxin ~]# sed '3{d;}' /etc/passwd
-[root@wxin ~]# sed '3{d}' /etc/passwd
-[root@wxin ~]# sed '$d' /etc/passwd
-[root@wxin ~]# sed '/north/d' /etc/passwd
-[root@wxin ~]# sed '/sout/d' /etc/passwd
-```
-
-**插入追加修改文本**
-
- `sed`编辑器使用`i`命令来向数据流中插入文本行,使用`a`命令来向数据流中附加文本行。其中`i`命令会在指定行前增加一个新行;`a`命令会在指定行后增加一个新行。
-
-注意:
-
- 这两个命令都不能在单行上使用(即不是用来在一行中插入或附加一段文本的),只能指定插入还是附加到另一行。
-
-```bash
-[root@wxin ~]# sed '[address][i | a] newline' file
-
-[root@wxin ~]# sed 'i\Insert a line behind every line' /etc/passwd # 向数据流的每一行前面增加一个新行,新行的内容为 \ 后面的内容
-[root@wxin ~]# sed '1i\Insert a line behind the first line' /etc/passwd # 在数据流的第一行前面增加一个新行
-[root@wxin ~]# sed '3a\Append a line after the third line' /etc/passwd # 在数据流的第三行后面增加一个新行
-[root@wxin ~]# sed '$a\Append a line in the last line' /etc/passwd # 在数据流的最后一行后面增加一个新行
-```
-
- 使用命令`c`可以将数据流中的整行文本修改为新的行,与插入、附加操作一样,这要求在`sed`命令中指定新的行
-
-```bash
-[root@wxin ~]# sed '[address][c] newtext' file
-
-[root@wxin ~]# sed '3 c\New text' /etc/passwd # 将数据流中第三行的内容修改为 \ 后面的内容
-[root@wxin ~]# sed '/root/ c\New text' /etc/passwd # 将匹配到 root 的行的内容修改为 \ 后面的内容
-[root@wxin ~]# sed '2,4c\New text' /etc/passwd # 将第2到4行的内容修改为 \ 后面的内容,但是不是逐行修改,而是会将这之间的 3 行用一行文本来替代
-```
-
-**`y`逐字符转换**
-
-```shell
-[address]y/inchars/outchars/
-```
-
- 转换命令会对 inchars 和 outchars 的值进行一对一的映射。inchars 中的第一个字符会被转换成 outchars 中的第一个字符;inchars 中的第二个字符会被转换成 outchars 中的第二个字符;... 直到处理完一行。如果 inchars 和 outchars 的长度不同,则 sed 编辑器会产生一个错误消息。举个例子:
-
-```bash
-[root@wxin ~]# echo abcdefggfedcba | sed 'y/acg/ACG/'
- AbCdefGGfedCbA
-```
-
-**`w`保存数据到文件**
-
-```bash
-[address]w filename
-
-
-[root@wxin ~]# sed '1,2w test.txt' /etc/passwd
-[root@wxin ~]# sed -n 's/root/ROOT/g w change.txt' /etc/passwd # 将 /etc/passwd 中所有的 root 都替换成 ROOT,并将被修改的行保存到文change.txt 中去
-```
-
-该语句将数据流的第 1、2 行写入文件 test.txt 中去。
-
-**`r`从文件中读取数据**
-
- 可以使用 r 命令来将一个文本中的数据插入到数据流中去,与普通的插入命令 i 类似,这也是对行进行操作的,命令格式如下:
-
-```shell
-[address]r filename
-```
-
- filename 为要插入的文件。r 命令常结合行寻址使用,以将文本插入到指定的行后面。
-
-```bash
-[root@wxin ~]# sed '3 r test.txt' /etc/passwd
-```
-
-这句话将文件 test.txt 中的内容插入到数据流第三行后面去。
-
-### 5. 模式空间和保持空间
-
- 模式空间和保持空间是两个独立的缓冲区,可以进行交互,命令可以寻址模式空间但是不能寻址保持空间。
-
-- 模式空间:容纳当前输入行的缓冲区,通过模式匹配到的行被读入模式空间中。用来进行进一步的操作;在多行模式中,`\n`可以用来和模式空间(`N`命令的结果)的任意换行符匹配,单模式空间底部的换行符除外。`^`匹配多行的首,`$`匹配多行的尾,不是每行的行首和行尾
-- 保持空间:`sed`在处理文本的时候都是在模式空间中进行,但有时候有些复杂的操作单一的模式空间可能无法满足需求,于是就有了保持空间,这个空间通常是空闲的,并不处理数据,只在有需要的时候和模式空间进行一些必要的数据交换。
-
-下面是模式空间中的常用命令。
-
-- h: 把模式空间中的内容覆盖至保持空间中
-- H:把模式空间中的内容追加至保持空间中
-- g: 从保持空间取出数据覆盖至模式空间
-- G:从保持空间取出内容追加至模式空间
-- x: 把模式空间中的内容与保持空间中的内容进行互换
-
-**多行模式空间**
-
- sed命令都是一行一行的进行处理文本的,不过有些时候单行处理可能并不能满足我们的需要,所以sed还提供了多行模式,多行模式的命令主要有 NPD 三个
-
-- N:读取匹配到的行的下一行追加至模式空间
-- P:打印模式空间开端至\n内容,并追加到默认输出之前
-
-- D:如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本, 并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间 不包含换行符,则会像发出d命令那样启动正常的新循环
-
-N命令流程图,P 和 D 命令在懂了N命令之后也容易理解。
-
-
-
-**示例:**
-
-```bash
-[root@wxin ~]# cat /etc/passwd |sed -n '2{N;p}'
-bin:x:1:1:bin:/bin:/sbin/nologin
-daemon:x:2:2:daemon:/sbin:/sbin/nologin
-# 读取第二行的下一行,然后输出模式空间中的内容,此时模式空间中有两行
-
-[root@wxin ~]# cat /etc/passwd |sed -n '2{N;N;N;p}'
-bin:x:1:1:bin:/bin:/sbin/nologin
-daemon:x:2:2:daemon:/sbin:/sbin/nologin
-adm:x:3:4:adm:/var/adm:/sbin/nologin
-lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
-# 使用多个N命令可以读取多行进模式空间
-
-[root@wxin ~]# seq 1 6| sed -n '1,2H;4p;5{x;p}'
-4
-
-1
-2
-```
-
- -n 是不显示默认输出内容,1,2H是将前两行追加至保持空间,4p显示第四行,5{x;p}是在第五行的时候交换保持空间和模式空间中的内容并且输出。注意输出中的空行,这是因为H命令追加的时候是添加换行符,由于保持空间默认是空的,所以添加换行符之后就多了一个空行。以用下面的命令先往保持空间覆盖一行然后追加。
-
-```bash
-[root@wxin ~]# seq 1 6| sed -n '1h;2H;4p;5{x;p}'
-4
-1
-2
-```
-
-- 第一个循环结束之后:模式空间为空,保持空间为第一行内容
-- 第二个循环,将第二行追加到模式空间,此时模式空间为两行内容
-- 第三个循环,没有匹配内容,不执行操作,模式空间和保持空间内容不变
-- 第四个循环,读取第四行并输出,保持空间内容不变
-- 第五个循环,读入第五行,然后和保持空间中的内容交换,之后输出。
-
-```bash
-# 暂存和取用命令:h H g G
-[root@wxin ~]# sed -r '1h;$G' /etc/hosts
-[root@wxin ~]# sed -r '1{h;d};$G' /etc/hosts
-[root@wxin ~]# sed -r '1h; 2,$g' /etc/hosts
-[root@wxin ~]# sed -r '1h; 2,3H; $G' /etc/hosts
-
-# 暂存空间和模式空间互换命令:x
-[root@wxin ~]# sed -r '4h; 5x; 6G' /etc/hosts
-```
-
+Shell Sed编译器
+
+------
+
+## 一:非交互式编译器 sed
+
+### 1. sed 介绍
+
+ Linux 中,常使用流编辑器`Sed`进行文本替换工作。与交互式编辑器(如vim)不同,`Sed`编辑器以批处理的方式来编辑文件,这比交互式编辑器快得多,可以快速完成对数据的编辑修改。`Sed`编辑器会执行以下操作:
+
+- 一次从输入中读取一行数据;
+- 根据所提供的编辑器命令匹配数据;
+- 按照命令修改流中的数据;
+- 将新的数据输出到`STDOUT`。
+
+ 在 Sed 编辑器匹配完一行数据后,它会读取下一行数据并重复这个过程,直到处理完所有数据。使用 Sed 命令打开一个 Sed 编辑器。
+
+
+
+ `sed`是一种在线的、非交互式的编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(`pattern space`),接着用`sed`命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。`Sed`主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
+
+### 2. 语法格式
+
+```shell
+sed [options] 'command' file
+```
+
+**options【选项】**
+
+| 选项 | 作用 |
+| :--: | :----------------------------------------------------------: |
+| `-n` | 只有经过sed处理的行才会被列出 |
+| `-e` | 允许多点编辑 |
+| `-f` | 将sed的动作写在一个文本内,-f filename 则可以执行filename内的sed动作。 |
+| `-r` | 支持扩展正则 |
+| `-i` | 直接修改源文件 |
+
+**command【子命令】**
+
+| 子命令 | 作用 |
+| :----: | :------------------------------------------: |
+| `a` | 在指定行**之后**追加文本 |
+| `i` | 在指定行**之前**插入文本 |
+| `c` | 替换整行内容 |
+| `d` | 删除指定行 |
+| `w` | 将匹配行的内容写入外部文件 |
+| `y` | 按字符一一映射替换 |
+| `p` | 打印匹配的行(通常与 `-n` 静默模式结合使用) |
+| `r` | 从外部文件读取内容并插入到指定行后 |
+| `q` | 匹配到指定行后立即退出处理 |
+| `=` | 输出行号(行号单独显示,原行内容不变) |
+| `s` | 替换匹配的文本 |
+| `!` | 对匹配条件取反 |
+| `g` | 在 `s` 命令中替换所有匹配项 |
+| `数字` | 指定行号或范围 |
+
+**特殊子命令**
+
+| 子命令 | 作用 |
+| :----: | :------------------------------------: |
+| `h` | 将模式空间内容**覆盖**到保持空间 |
+| `H` | 将模式空间内容**追加**到保持空间 |
+| `g` | 用保持空间内容**覆盖**模式空间 |
+| `G` | 将保持空间内容**追加**到模式空间 |
+| `x` | 交换两个空间的内容 |
+| `n` | 读取下一行覆盖当前模式空间 |
+| `N` | 追加下一行到当前模式空间(合并多行) |
+| `P` | 打印多行模式空间的第一行 |
+| `D` | 删除多行模式空间的第一行并重新开始循环 |
+
+### 3. 定址
+
+ 默认`sed`对文件中的所有行进行编辑。当然,也可以只指定特定的某些行,或者行范围进行流编辑,这需要用到行寻址。所指定的行地址放在子命令之前
+
+```shell
+[address]command
+```
+
+**数字定址**
+
+ `sed`编辑器将文本流中的每一行都进行编号,第一行的编号为 1 ,后面的按顺序分配行号。通过指定特定的行号,可以选择编辑特定的行。
+
+```bash
+# 将第3行中所有的 bin 替换成 BIN
+[root@wxin ~]# sed '3 s/bin/BIN/g' /etc/passwd
+
+# 将第2到5行中所有的 bin 替换成 BIN
+[root@wxin ~]# sed '2,5 s/bin/BIN/g' /etc/passwd
+
+# 将第10行到最后一行中所有的 bin 替换成 BIN
+[root@wxin ~]# sed '10,$ s/bin/BIN/g' /etc/passwd
+```
+
+**正则定址**
+
+ `sed`编辑器允许使用正则过滤出命令要作用的行
+
+```shell
+/pattern/command
+```
+
+ 必须使用" / " 将要指定的 pattern 包起来。sed 会寻找匹配文本模式的行,然后对这些行执行编辑命令
+
+```bash
+[root@wxin ~]# sed -n '/root/s/bin/BIN/p' /etc/passwd
+
+# 寻找包含有字符串 root 的行,并将匹配行的 bin 替换为 BIN
+```
+
+ 与数字寻址一样,也可以使用正则过滤区间来过滤行。
+
+```bash
+[root@wxin ~]# sed '/pattern1/,/pattern2/ edit_command' file
+```
+
+ 这行命令会在文件 file 中先寻找匹配 pattern1 的行,然后从该行开始,执行编辑命令,直到找到匹配 pattern2 的行。但是需要注意的是,使用文本区间过滤文本时,只要匹配到了开始模式(pattern1),编辑命令就会开始执行,直到匹配到结束模式(pattern2),这会导致一种情况:一个文本中,先匹配到了一对 pattern1、pattern2,对该文本区间中的文本执行了编辑命令;然后,在 pattern2 之后又匹配到了 pattern1,这时就会再次开始执行编辑命令,因此,在使用文本区间过滤时要注意这一点。
+
+```bash
+[root@wxin ~]# sed -n '/root/,/nologin/ s/bin/BIN/p' /etc/passwd
+root:x:0:0:root:/root:/BIN/bash
+BIN:x:1:1:bin:/bin:/sbin/nologin
+operator:x:11:0:operator:/root:/sBIN/nologin
+games:x:12:100:games:/usr/games:/sBIN/nologin
+```
+
+### 4. 示例
+
+**`s`替换**
+
+使用`s`命令来进行文本替换
+
+```bash
+[root@wxin ~]# sed 's/srcStr/dstStr/' file
+```
+
+ 其中,`srcStr`为想要替换的文本,`dstStr`为将要替换成的文本。使用`s`命令时,`sed`编辑器会在一行一行地读取文件`file`,并在每行查找文本`srcStr`,如果找到了,则将该处的`srcStr`替换为`dstStr`。
+
+ `/`字符为界定符,用于分隔字符串(`sed`编辑器允许使用其他字符作为替换命令中的字符串分隔符):
+
+```bash
+[root@wxin ~]# sed 's!/bin/bash!/BIN/BASH!' /etc/passwd # 使用 ! 作为字符串分隔符
+[root@wxin ~]# sed 's#3#88#g' datafile
+```
+
+ 默认,`s`只会替换掉目标文本在每行中第一次出现的地方。若想要替换掉每行中所有匹配的地方,可以使用替换标记`g`。替换标记放在编辑命令的末尾。除了`g`外,还有几种替换标记:
+
+1. 数字指明替换掉第几次匹配到的文本
+
+ 没有设置这个标记时,默认是替换第一次匹配的文本
+
+ ```bash
+ [root@wxin ~]# sed 's/root/ROOT/2' /etc/passwd
+ ```
+
+ 这行命令将`/etc/passwd`文件中每行的第`2`个`root`替换为`ROOT`
+
+2. g 替换所有匹配到的文本
+
+ ```bash
+ [root@wxin ~]# sed 's/root/ROOT/g' /etc/passwd
+ ```
+
+ 这行命令将`/etc/passwd`文件中的`root`,全部替换为`ROOT`;
+
+3. p 打印与替换命令中指定模式(srcStr)相匹配的行
+
+ ```bash
+ [root@wxin ~]# sed 's/root/ROOT/p' /etc/passwd
+ ```
+
+ 执行这命令,会在 STDOUT 上看到包含有 root 的行被输出了两次,一次是 sed 编辑器自动输出的;另一次则是 p 标记打印出来的匹配行
+
+ ```bash
+ [root@wxin ~]# sed -n 's/root/ROOT/gp' /etc/passwd # 将 /etc/passwd 中所有的 root 都替换成 ROOT,并输出被修改的行
+ ```
+
+**`d`删除**
+
+ `sed`编辑器使用`d`命令来删除文本流中的特定行。使用`d`命令时,一般需要带上位寻址,以删除指定的行,否则默认会删除所有文本行。
+
+```bash
+[root@wxin ~]# sed '/root/d' /etc/passwd # 删除匹配 root 的行
+
+[root@wxin ~]# sed '2,$d' /etc/passwd # 删除第2到最后一行
+
+[root@wxin ~]# sed '3d' /etc/passwd
+[root@wxin ~]# sed '3{d;}' /etc/passwd
+[root@wxin ~]# sed '3{d}' /etc/passwd
+[root@wxin ~]# sed '$d' /etc/passwd
+[root@wxin ~]# sed '/north/d' /etc/passwd
+[root@wxin ~]# sed '/sout/d' /etc/passwd
+```
+
+**插入追加修改文本**
+
+ `sed`编辑器使用`i`命令来向数据流中插入文本行,使用`a`命令来向数据流中附加文本行。其中`i`命令会在指定行前增加一个新行;`a`命令会在指定行后增加一个新行。
+
+注意:
+
+ 这两个命令都不能在单行上使用(即不是用来在一行中插入或附加一段文本的),只能指定插入还是附加到另一行。
+
+```bash
+[root@wxin ~]# sed '[address][i | a] newline' file
+
+[root@wxin ~]# sed 'i\Insert a line behind every line' /etc/passwd # 向数据流的每一行前面增加一个新行,新行的内容为 \ 后面的内容
+[root@wxin ~]# sed '1i\Insert a line behind the first line' /etc/passwd # 在数据流的第一行前面增加一个新行
+[root@wxin ~]# sed '3a\Append a line after the third line' /etc/passwd # 在数据流的第三行后面增加一个新行
+[root@wxin ~]# sed '$a\Append a line in the last line' /etc/passwd # 在数据流的最后一行后面增加一个新行
+```
+
+ 使用命令`c`可以将数据流中的整行文本修改为新的行,与插入、附加操作一样,这要求在`sed`命令中指定新的行
+
+```bash
+[root@wxin ~]# sed '[address][c] newtext' file
+
+[root@wxin ~]# sed '3 c\New text' /etc/passwd # 将数据流中第三行的内容修改为 \ 后面的内容
+[root@wxin ~]# sed '/root/ c\New text' /etc/passwd # 将匹配到 root 的行的内容修改为 \ 后面的内容
+[root@wxin ~]# sed '2,4c\New text' /etc/passwd # 将第2到4行的内容修改为 \ 后面的内容,但是不是逐行修改,而是会将这之间的 3 行用一行文本来替代
+```
+
+**`y`逐字符转换**
+
+```shell
+[address]y/inchars/outchars/
+```
+
+ 转换命令会对 inchars 和 outchars 的值进行一对一的映射。inchars 中的第一个字符会被转换成 outchars 中的第一个字符;inchars 中的第二个字符会被转换成 outchars 中的第二个字符;... 直到处理完一行。如果 inchars 和 outchars 的长度不同,则 sed 编辑器会产生一个错误消息。举个例子:
+
+```bash
+[root@wxin ~]# echo abcdefggfedcba | sed 'y/acg/ACG/'
+ AbCdefGGfedCbA
+```
+
+**`w`保存数据到文件**
+
+```bash
+[address]w filename
+
+
+[root@wxin ~]# sed '1,2w test.txt' /etc/passwd
+[root@wxin ~]# sed -n 's/root/ROOT/g w change.txt' /etc/passwd # 将 /etc/passwd 中所有的 root 都替换成 ROOT,并将被修改的行保存到文change.txt 中去
+```
+
+该语句将数据流的第 1、2 行写入文件 test.txt 中去。
+
+**`r`从文件中读取数据**
+
+ 可以使用 r 命令来将一个文本中的数据插入到数据流中去,与普通的插入命令 i 类似,这也是对行进行操作的,命令格式如下:
+
+```shell
+[address]r filename
+```
+
+ filename 为要插入的文件。r 命令常结合行寻址使用,以将文本插入到指定的行后面。
+
+```bash
+[root@wxin ~]# sed '3 r test.txt' /etc/passwd
+```
+
+这句话将文件 test.txt 中的内容插入到数据流第三行后面去。
+
+### 5. 模式空间和保持空间
+
+ 模式空间和保持空间是两个独立的缓冲区,可以进行交互,命令可以寻址模式空间但是不能寻址保持空间。
+
+- 模式空间:容纳当前输入行的缓冲区,通过模式匹配到的行被读入模式空间中。用来进行进一步的操作;在多行模式中,`\n`可以用来和模式空间(`N`命令的结果)的任意换行符匹配,单模式空间底部的换行符除外。`^`匹配多行的首,`$`匹配多行的尾,不是每行的行首和行尾
+- 保持空间:`sed`在处理文本的时候都是在模式空间中进行,但有时候有些复杂的操作单一的模式空间可能无法满足需求,于是就有了保持空间,这个空间通常是空闲的,并不处理数据,只在有需要的时候和模式空间进行一些必要的数据交换。
+
+下面是模式空间中的常用命令。
+
+- h: 把模式空间中的内容覆盖至保持空间中
+- H:把模式空间中的内容追加至保持空间中
+- g: 从保持空间取出数据覆盖至模式空间
+- G:从保持空间取出内容追加至模式空间
+- x: 把模式空间中的内容与保持空间中的内容进行互换
+
+**多行模式空间**
+
+ sed命令都是一行一行的进行处理文本的,不过有些时候单行处理可能并不能满足我们的需要,所以sed还提供了多行模式,多行模式的命令主要有 NPD 三个
+
+- N:读取匹配到的行的下一行追加至模式空间
+- P:打印模式空间开端至\n内容,并追加到默认输出之前
+
+- D:如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本, 并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间 不包含换行符,则会像发出d命令那样启动正常的新循环
+
+N命令流程图,P 和 D 命令在懂了N命令之后也容易理解。
+
+
+
+**示例:**
+
+```bash
+[root@wxin ~]# cat /etc/passwd |sed -n '2{N;p}'
+bin:x:1:1:bin:/bin:/sbin/nologin
+daemon:x:2:2:daemon:/sbin:/sbin/nologin
+# 读取第二行的下一行,然后输出模式空间中的内容,此时模式空间中有两行
+
+[root@wxin ~]# cat /etc/passwd |sed -n '2{N;N;N;p}'
+bin:x:1:1:bin:/bin:/sbin/nologin
+daemon:x:2:2:daemon:/sbin:/sbin/nologin
+adm:x:3:4:adm:/var/adm:/sbin/nologin
+lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
+# 使用多个N命令可以读取多行进模式空间
+
+[root@wxin ~]# seq 1 6| sed -n '1,2H;4p;5{x;p}'
+4
+
+1
+2
+```
+
+ -n 是不显示默认输出内容,1,2H是将前两行追加至保持空间,4p显示第四行,5{x;p}是在第五行的时候交换保持空间和模式空间中的内容并且输出。注意输出中的空行,这是因为H命令追加的时候是添加换行符,由于保持空间默认是空的,所以添加换行符之后就多了一个空行。以用下面的命令先往保持空间覆盖一行然后追加。
+
+```bash
+[root@wxin ~]# seq 1 6| sed -n '1h;2H;4p;5{x;p}'
+4
+1
+2
+```
+
+- 第一个循环结束之后:模式空间为空,保持空间为第一行内容
+- 第二个循环,将第二行追加到模式空间,此时模式空间为两行内容
+- 第三个循环,没有匹配内容,不执行操作,模式空间和保持空间内容不变
+- 第四个循环,读取第四行并输出,保持空间内容不变
+- 第五个循环,读入第五行,然后和保持空间中的内容交换,之后输出。
+
+```bash
+# 暂存和取用命令:h H g G
+[root@wxin ~]# sed -r '1h;$G' /etc/hosts
+[root@wxin ~]# sed -r '1{h;d};$G' /etc/hosts
+[root@wxin ~]# sed -r '1h; 2,$g' /etc/hosts
+[root@wxin ~]# sed -r '1h; 2,3H; $G' /etc/hosts
+
+# 暂存空间和模式空间互换命令:x
+[root@wxin ~]# sed -r '4h; 5x; 6G' /etc/hosts
+```
+