2021-11-14 15:52:46 +08:00

180 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "sed 命令"
date: 2019-10-30T00:56:26+08:00
lastmod: 2019-10-30T00:56:26+08:00
keywords: []
tags: ["sed"]
categories: ["shell"]
---
## 流程
- 每次从输入中读取一行
- 匹配数据
- 修改数据
- 输出数据(默认 stdout)
## 选项
- -e 执行多个编辑命令
```bash
sed -e 's/root/ROOT/g; s/bin/BIN/g' /etc/passwd
sed -e 's/root/ROOT/g' -e 's/bin/BIN/g' /etc/passwd
```
- -f 从指定文件中获取 sed 命令
```bash
cat > script.sed <<EOF
s/root/ROOT/
s/bin/BIN/
s/home/HOME/
EOF
sed -f script.sed /etc/passwd
```
- -n 不输出数据(只是编辑器不输出,与编辑命令无关)
- -i 直接修改文件本身
- -r 扩展正则表达式,不需要繁琐的转义
## 命令
命令 | 描述
---- | ----
s | 替换文本
d | 删除行
i | 匹配行上插入新行
a | 匹配行下插入新行
c | 匹配行替换
y | 逐个字符替换文本
p | 打印行
= | 打印行号
w | 写入指定文件
r | 读出指定文件
## 高级命令
命令 | 描述
---- | ----
x | 交换模式空间与保持空间内容
d | 删除当前模式空间内容,并进入下一个循环
D | 删除多行模式空间中的首行,并进入下一个循环
n | 读取匹配到的下一行至模式空间 [会覆盖模式空间原有的值]
N | 读取匹配到的下一行至模式空间 [追加到原有内容后]
h | 复制模式空间内容,到保持空间, 覆盖
H | 复制模式空间内容,到保持空间, 追加
g | 复制保持空间内容,到模式空间, 覆盖
G | 复制保持空间内容,到模式空间, 追加
- 模式空间(pattern space): 所有的处理动作都在这里,默认打印到终端
- 保持空间(hold space): 数据暂存区域,类似中间变量
- 循环标签
- 格式: sed -n ':标签名 范围1 命令1; /模式/b 标签名' filename
- 调用: b, t, T
## 使用
- 默认只替换在每行第一次出现目标文本
```bash
sed 's/root/ROOT/' /etc/passwd
```
- 数字替换标记,替换每行的第二个 root 为 ROOT
```bash
sed 's/root/ROOT/2' /etc/passwd
```
- g 替换标记,替换所有匹配的 root 为 ROOT
```bash
sed 's/root/ROOT/g' /etc/passwd
```
- 替换每行第二次开始及之后的 root 为 ROOT
```bash
sed 's/root/ROOT/2g' /etc/passwd
```
- 打印被替换过的行
```bash
sed -n 's/root/ROOT/gp' /etc/passwd
```
- 把被替换过的行写入 change.txt 中
```bash
sed -n 's/root/ROOT/g w change.txt' /etc/passwd
```
- 将第3行中所有的 bin 替换成 BIN
```bash
sed '3 s/bin/BIN/g' /etc/passwd
```
- 将第2到5行中所有的 bin 替换成 BIN
```bash
sed '2,5 s/bin/BIN/g' /etc/passwd
```
- 将第10行到最后一行中所有的 bin 替换成 BIN
```bash
sed '10,$ s/bin/BIN/g' /etc/passwd
```
- 寻找包含有字符串 root 的行,并将匹配行的 bin 替换为 BIN
```bash
sed -n '/root/s/bin/BIN/p' /etc/passwd
```
- 从匹配 root 的行开始替换 bin 为 BIN直到匹配 nologin 的行,循环
```bash
sed -n '/root/,/nologin/s/bin/BIN/p' /etc/passwd
```
- 删除匹配 root 的行
```bash
sed '/root/d' /etc/passwd
```
- 删除第2到最后一行
```bash
sed '2,$d' /etc/passwd
```
- 删除匹配 root 行及其下面两行
```bash
sed '/root/,+2d' /etc/passwd
```
- 保留第四、五、六三行,其他行删除
```bash
sed '4,6!d' /etc/passwd
```
- 每一行前面增加一个行 AAAA
```bash
sed 'iAAAA' /etc/passwd
```
- 第一行前面增加一个行 AAAA
```bash
sed '1iAAAA' /etc/passwd
```
- 第三行后面增加一个行 AAAA
```bash
sed '3aAAAA' /etc/passwd
```
- 最后一行后面增加一个行 AAAA
```bash
sed '$aAAAA' /etc/passwd
```
- 逐个字符替换
```bash
echo abcdefggfedcba | sed 'y/acg/ACG/'
# 输出 AbCdefGGfedCbA
```
- 把第1行到第4行写入 test.txt
```bash
sed '1,4w test.txt' /etc/passwd
```
- 把 test.txt 的内容插入第三行后
```bash
sed '3r test.txt' /etc/passwd
```
- 把 000_00000000 换成 000.00000000
```bash
sed -i 's/\([0-9]\{3\}\)_\([0-9]\{8\}\)/\1.\2/g' phone_file
# 或者
sed -i -r 's/([0-9]{3})_([0-9]{8})/\1.\2/g' phone_file
```
- 替换 root 为 (root)
```bash
sed -i 's/root/(&)/g' file_name
```
- 把匹配 AAAA 行下的第二行中的 BBBB 改成 CCCC
```bash
sed -i '/AAAA/{n;n;s/BBBB/CCCC/g}' file_name
```
- 在匹配 AAAA 行下的第三行下添加 CCCC 一行
```bash
sed -i '/AAAA/{n;n;n;s/$/\nCCCC/}' file_name
```
## 参考
- [Sed 介绍和教程](https://www.cnblogs.com/cbscan/articles/2277351.html)