目录
简介:
Sed 是一种流式文本编辑器,它逐行读取输入文本(文件或管道数据),根据预设的编辑指令对每一行执行文本处理操作(如替换、删除、插入等),并立即将处理后的结果逐行输出到标准输出流中,整个过程高效且无需将整个文件加载到内存。
基本语法:
bash
sed [选项] '命令' 文件
sed [选项] -e '命令1' -e '命令2' 文件
sed [选项] -f 脚本文件 文件
文件准备:
首先准备一个具有如下内容的文件
file.txt
bash
This is the first line.
This line contains pattern and more pattern.
The Pattern is here with Pattern.
Line with numbers 123.
Empty line below:
This line contains ab, abc, abab
inline should not match.
This line ends with file.
T.h matches this.
aaa and aaaa here.
a or b in this line.
x y z only.
This starts here.
last line for testing.
aa
aaaaa
b
c
ab
multiline.txt
bash
first line with line pattern
second line without
third line with pattern again
last line in this file
passwd
bash
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
john:x:1001:1001:John Doe:/home/john:/bin/bash
mary:x:1002:1002:Mary Smith:/home/mary:/bin/bash
sample.html
bash
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<h1>Welcome</h1>
<p>This is a <strong>sample</strong> paragraph.</p>
<div>More content here</div>
</body>
</html>
注:以下命令不加-i选项的,都不会对原文件进行改变,只是把更改后的结果输出到终端!!!!!
替换命令(s)
1.基本替换,默认只替换每行中的第一个
bash
# 基本替换 - 只替换每行第一个匹配项
echo "=== 基本替换,默认只替换每行中第一个 ==="
sed 's/pattern/PATTERN/' file.txt
运行结果图:
如下所示在第二行只把第一个pattern替换成大写了

2.全局替换
在最后增加了选项g表示替换所有的
bash
# 全局替换 - 替换每行所有匹配项
echo -e "\n=== 全局替换 ==="
sed 's/line/LINE/g' file.txt
运行图如下所示:

3.替换指定匹配项
bash
# 只替换第几个匹配项
echo -e "\n=== 替换第二个匹配项 ==="
sed 's/line/LINE/2' multiline.txt
运行结果图:
仅仅替换了每行中的第二个出现的line

4.忽略大小写替换
bash
# 忽略大小写替换
echo -e "\n=== 忽略大小写替换 ==="
sed 's/pattern/REPLACEMENT/gi' file.txt
运行结果图:
在g后加上i就是在全局替换的基础上忽略大小写

5.使用不同分隔符
注:再次替换/bin/bash中存在'/',所以使用'|'进行分割
bash
# 使用不同分隔符
echo -e "\n=== 使用不同分隔符 ==="
sed 's|/bin/bash|/bin/sh|g' passwd
运行结果图:

6.替换并保存到原文件中
bash
# 替换并保存到文件(演示,但不实际修改原文件)
echo -e "\n=== 替换并显示(修改原文件) ==="
sed -i 's/pattern/REPLACEMENT/g' file.txt
运行结果:
加 -i 对原文件影响

删除命令
1.删除第三行
注:加d就是删除
bash
# 删除第3行
echo "=== 删除第3行 ==="
sed '3d' file.txt
运行图:

2.删除第3到第5行
bash
# 删除第3到第5行
echo -e "\n=== 删除第3到第5行 ==="
sed '3,5d' file.txt
运行图:

3.删除最后一行
bash
# 删除最后一行
echo -e "\n=== 删除最后一行 ==="
sed '$d' file.txt
运行图如下:

4.删除包含特定模式的行
注:/ /之间定义选中的目标d为删除操作
bash
# 删除包含特定模式的行
echo -e "\n=== 删除包含'pattern'的行 ==="
sed '/pattern/d' file.txt
运行结果图:

5.删除空行
bash
# 删除空行
echo -e "\n=== 删除空行 ==="
sed '/^$/d' file.txt
运行图:

6.删除从匹配行到文件末尾的所有行
注:a,b就是从a到b。在这里就是匹配到第一个含last的行,$就是到最后一行,最后的d代表删除
bash
# 删除从匹配行到文件末尾的所有行
echo -e "\n=== 删除从包含'last'的行到文件末尾 ==="
sed '/last/,$d' file.txt
运行图:

插入命令
1.在第二行前插入文本
注:2代表第2行,i代表要进行插入操作,\后面是插入的内容
bash
# 在第2行前插入文本
echo "=== 在第2行前插入文本 ==="
sed '2i\This is inserted line' file.txt
运行图:

2.在第二行后追加文本
注:a表示进行追加操作,2代表在第2行后追加,\后表示插入的内容
bash
# 在第2行后追加文本
echo -e "\n=== 在第2行后追加文本 ==="
sed '2a\This is appended line' file.txt
运行图:

3.替换第二行内容
注:c表示进行替换操作,2代表替换第2行的内容,\后表示替换的内容
bash
# 替换第2行内容
echo -e "\n=== 替换第2行内容 ==="
sed '2c\This replaces line 2' file.txt
运行图:

4.在匹配行前插入
注:i表示进行插入操作,/Pattern/表示匹配对应的行,\后表示插入的内容
bash
# 在匹配行前插入
echo -e "\n=== 在包含'pattern'的行前插入 ==="
sed '/Pattern/i\--- INSERTED BEFORE PATTERN ---' file.txt
运行图:

打印命令
1.打印第三行
注:-n 是 抑制 sed 的默认输出行为,就是只打印选中那一行,不打印其他行,p代表打印操作,3是第三行
bash
# 打印第3行
echo "=== 打印第3行 ==="
sed -n '3p' file.txt
运行图:

2.打印第3到第5行
注:3,5代表3到5行
bash
# 打印第3到第5行
echo -e "\n=== 打印第3到第5行 ==="
sed -n '3,5p' file.txt
运行图:

3.打印匹配行
bash
# 打印匹配行
echo -e "\n=== 打印包含'pattern'的行 ==="
sed -n '/Pattern/p' file.txt
运行图:

4.打印包含数字的行
注:匹配包含0-9任意数字的行
bash
# 打印包含数字的行
echo -e "\n=== 打印包含数字的行 ==="
sed -n '/[0-9]/p' file.txt
运行图:

范围内替换
1.单行替换
注:这个后面没有加g所以只会将第五行第一个line替换为LINE
bash
# 单行替换
echo "=== 单行替换(第5行)==="
sed '5s/line/LINE/' file.txt
运行图:

2.在范围内替换
bash
# 范围替换
echo -e "\n=== 范围替换(第3到第7行)==="
sed '3,7s/line/LINE/g' file.txt
运行图:

3.从某行到文件末尾
注:g表示全局替换
bash
# 从某行到文件末尾
echo -e "\n=== 从第5行到末尾替换 ==="
sed '5,$s/line/LINE/g' file.txt
运行图:

4.从第一个匹配到第二个匹配行
bash
# 从第一个匹配到第二个匹配
echo "=== 从第一个'first'到第一个'last'之间替换 ==="
sed '/first/,/last/s/line/LINE/g' multiline.txt
如图:

实际应用----文本处理
1.删除HTML标签
注:^在中括号内表示非,*代表0次或多次,所以该语句代表,将标签内(<>标签内)不是>的内容全局替换为空。
bash
# 删除HTML标签
echo "=== 删除HTML标签 ==="
sed 's/<[^>]*>//g' sample.html
运行如图:

2.合并多行到一行
注:
:a标记一个位置,供后续跳转使用
N追加到模式空间,比如将第二行追加,和第一行用换行符隔开
$!ba 表示如果不是最后一行就跳转到a所在位置
最后将所有换行符替换为空格
大概流程:
读取第1行 → 标记a → 追加第2行 → 不是最后一行? → 是 → 跳回a
↑ ↓
↑ ↓
←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
读取第2行后 → 追加第3行 → 不是最后一行? → 否 → 继续执行
↓
替换换行为空格
↓
输出结果
bash
# 合并多行到一行
echo -e "\n=== 合并多行 ==="
sed ':a;N;$!ba;s/\n/ /g' file.txt | head -1
如图:

3.给文件添加行号
注:
1.首先在每一行前插入=号将处理完的结果输出到后面命令
2.取第1行"1"到模式空间,执行N:将下一行"第一行"追加到模式空间
bash
# 给文件添加行号
echo -e "\n=== 添加行号 ==="
sed '=' file.txt | sed 'N; s/\n/ /'
运行图:

4.将每行的第一个单词转为大写
注:
-
\U:开启大写转换 -
\1:第一个捕获组的内容(第一个小写字母) -
\E:结束大写转换 -
\2:第二个捕获组的内容(单词的剩余部分)
bash
# 将每行的第一个单词转为大写
echo -e "\n=== 首单词转大写 ==="
sed 's/^\([a-z]\)\([a-zA-Z]*\)/\U\1\E\2/' file.txt
运行图:

配置文件处理
1.注释掉特定配置项
注:找到对应的项开头,替换为#加上找到的项
bash
# 注释掉配置项
echo "=== 注释掉配置项 ==="
sed 's/^\(app\.debug=\)/#\1/' config.txt
运行图:

2.取消注释
bash
# 取消注释
echo -e "\n=== 取消注释 ==="
sed 's/^#\+\(.*app\.maintenance.*\)/\1/' config.txt
运行结果图:

3.修改配置值
注:先找到想改的对应行,然后将等号的值替换为false
bash
# 修改配置值
echo -e "\n=== 修改配置值 ==="
sed '/^app\.debug=/s/=.*/=false/' config.txt
运行结果:
