Linux的sed命令详解和实例
返回工具箱首页
在 Linux 和 Unix 系统中,sed(stream editor)是一款功能强大且灵活的文本处理工具。
1️⃣ 基本用法
sed 的基本语法如下:
sed [选项] '脚本/命令' 文件
选项:可以是 -e(表达式),-f(脚本文件)等。
脚本:包含一个或多个 sed 命令。
文件:要处理的文本文件。
1.1 🛠️ 常用选项
-e 脚本 或 --expression=脚本:直接在命令行中添加 sed 命令。
-f 脚本文件 或 --file=脚本文件:从指定的脚本文件中读取 sed 命令。
-n 或 --quiet 或 --silent:仅显示由 sed 命令处理的行。
-i[SUFFIX] 或 --in-place[=SUFFIX]:直接编辑文件内容,原文件内容会被替换,如果指定了 SUFFIX,则会保存备份。
- -r:支持扩展正则表达式。
1.2 🛠️ 常用命令
-
a:在当前行后追加文本。
-
i:在当前行前插入文本。
-
c:替换选定的行。
-
d:删除选定的行。
-
p:打印选定的行。
-
s:替换指定的字符。
1.3 🛠️ sed 命令 n,N,d,D,p,P,h,H,g,G,x
1、sed执行模板=sed '模式{命令1;命令2}' 即逐行读入模式空间,执行命令,最后输出打印出来。
2、先说下p和P,p打印当前模式空间内容,追加到默认输出之后,P打印当前模式空间开端至\n的内容,并追加到默认输出之前。sed并不对每行末尾\n进行处理,但是对N命令追加的行间\n进行处理,因为此时sed将两行看做一行。
2-1、n命令
n命令简单来说就是提前读取下一行,覆盖模型空间前一行(并没有删除,因此依然打印至标准输出),如果命令未执行成功(并非跳过:前端条件不匹配),则放弃之后的任何命令,并对新读取的内容,重头执行sed。
例子:
从aaa文件中取出偶数行
|
1
2
3
4
5
6
7
8
9
10
|
cat aaa
This is 1
This is 2
This is 3
This is 4
This is 5
sed -n 'n;p' aaa //-n 表示隐藏默认输出内容
This is 2
This is 4
|
注 释:读取This is 1,执行n命令,此时模式空间为This is 2,执行p,打印模式空间内容This is 2,之后读取 This is 3,执行n命令,此时模式空间为This is 4,执行p,打印模式空间内容This is 4,之后读取This is 5,执行n 命令,因为没有了,所以退出,并放弃p命令。
因此,最终打印出来的就是偶数行。
2-2、N命令
N命令简单来说就是追加下一行到模式空间,同时将两行看做一行,但是两行之间依然含有\n换行符,如果命令未执行成功(并非跳过:前端条件不匹配),则放弃之后任何命令,并对新读取的内容,重头执行sed。
例子:
从aaa文件中读取奇数行
|
1
2
3
4
5
6
7
8
9
10
11
|
cat aaa
This is 1
This is 2
This is 3
This is 4
This is 5
sed -n '$!N;P' aaa
This is 1
This is 3
This is 5
|
注释中1代表This is 1 2代表This is 2 以此类推
注释:读取1,$!条件满足(不是尾行),执行N命令,得出1\n2,执行P,打印得1,读取3,$!条件满足(不是尾行),执行N命令,得出3\n4,执行P,打印得3,读取5,$!条件不满足,跳过N,执行P,打印得5
2-3、d命令
d命令是删除当前模式空间内容(不在传至标准输出),并放弃之后的命令,并对新读取的内容,重头执行sed。
d命令例子
从aaa文件中取出奇数行
|
1
2
3
4
5
6
7
8
9
10
11
|
cat aaa
This is 1
This is 2
This is 3
This is 4
This is 5
sed 'n;d' aaa
This is 1
This is 3
This is 5
|
注释:读取1,执行n,得出2,执行d,删除2,得空,以此类推,读取3,执行n,得出4,执行d,删除4,得空,但是读取5时,因为n无法执行,所以d不执行。因无-n参数,故输出1\n3\n5
2-4、D命令
D命令是删除当前模式空间开端至\n的内容(不在传至标准输出),放弃之后的命令,但是对剩余模式空间重新执行sed。
D命令例子
从aaa文件中读取最后一行
|
1
2
3
4
5
6
7
8
9
|
cat aaa
This is 1
This is 2
This is 3
This is 4
This is 5
sed 'N;D' aaa
This is 5
|
注释:读取1,执行N,得出1\n2,执行D,得出2,执行N,得出2\n3,执行D,得出3,依此类推,得出5,执行N,条件失败退出,因无-n参数,故输出5
2-5、y命令
y命令的作用在于字符转换
y命令例子:
将aaa文件内容大写
|
1
2
3
4
5
6
|
sed 'y/his/HIS/' aaa
THIS IS 1
THIS IS 2
THIS IS 3
THIS IS 4
THIS IS 5
|
此外,如果需要对某个字符串进行大小写转换,则可使用如下方法
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
cat ddd
This is a and a is 1
This is b and b is 2
This is c and c is 3
This is d and d is 4
This is e and e is 5
sed 's/\b[a-z]\b/\u&/g' ddd
This is A and A is 1
This is B and B is 2
This is C and C is 3
This is D and D is 4
This is E and E is 5
|
2-6、h命令,H命令,g命令,G命令
h命令是将当前模式空间中内容覆盖至保持空间,H命令是将当前模式空间中的内容追加至保持空间
g命令是将当前保持空间中内容覆盖至模式空间,G命令是将当前保持空间中的内容追加至模式空间
命令例子:
将ddd文件中数字和字母互换,并将字母大写
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
cat ddd. sed
h
{
s/.*is \(.*\) and .*/\1/
y /abcde/ABCDE/
G
s/\(.*\)\n\(.*is \).*\(and \).*\(is \)\(.*\)/\2\5 \3\5 \4\1/
}
sed -f ddd. sed ddd
This is 1 and 1 is A
This is 2 and 2 is B
This is 3 and 3 is C
This is 4 and 4 is D
This is 5 and 5 is E
|
注释:读取1,执行h,复制到保持空间,执行s,模式空间得到匹配到的字母a,然后执行y,将a转成A,执行G,追加保持空间内容到模式空间,得
A\nThis is a and a is 1;执行s,重新排列,得出This is 1 and 1 is A;以此类推,得出结果。
这里需要注意的是匹配的内容中,空格一定要处理好,空格处理不对,会造成第二次s匹配错误,无法执行重新排列或排列错误
2-7、x命令
x命令是将当前保持空间和模式空间内容互换
2️⃣ 常用实例
2.1 🔄 替换文本 (s)
替换是 sed 最常用的功能之一。基本格式为:
sed 's/原文本/新文本/选项' 文件
g:全局替换,替换行内所有匹配的文本。
N:替换第 N 个匹配项。
示例:
sed 's/foo/bar/g' file.txt
sed 's/foo/bar/' file.txt
sed 's/foo/bar/2' file.txt
sed -i 's/foo/bar/g' file.txt
2.2 🗑️ 删除行 (d)
sed 可以根据条件删除行:
sed '2d' file.txt
sed '2,4d' file.txt
sed '/foo/d' file.txt
2.3 ➕ 插入和追加文本 (i 和 a)
在特定行前插入或在特定行后追加文本:
sed '2a\This is a new line' file.txt
sed '2i\This is a new line' file.txt
2.4 🔄 替换行 (c)
替换整行内容:
sed '2c\This is a new line' file.txt
sed '/foo/c\This line contains foo' file.txt
2.5 🖨️ 打印行 (p)
打印特定行:
sed -n '2p' file.txt
sed -n '2,4p' file.txt
sed -n '/foo/p' file.txt
2.6 🛠️ 多重编辑 (-e)
可以在一次 sed 调用中执行多个命令:
sed -e '1c\First line' -e '2d' file.txt
2.7 📜 使用脚本文件 (-f)
将多个 sed 命令写入脚本文件,并通过 -f 选项执行:
sed -f script.sed file.txt
3️⃣ 高级用法
3.1 🔄 替换文本并保留原始内容
可以使用 w 命令将修改后的内容写入新文件,同时保留原始文件:
sed 's/foo/bar/g; w newfile.txt' file.txt
3.2 🗑️ 删除空白行和包含仅有空白字符的行
sed '/^$/d' file.txt
sed '/^[[:space:]]*$/d' file.txt
3.3 📜 处理多行模式匹配
sed '/start/,/end/c\replaced' file.txt
3.4 🔄 使用正则表达式替换文本
sed '/^[0-9]/s/foo/bar/g' file.txt
sed -E 's/([0-9]{3})-([0-9]{3})-([0-9]{4})/(\1) \2-\3/g' file.txt
3.5 🔄 使用元字符处理文本
sed 's/^/START: /' file.txt
sed 's/$/ :END/' file.txt
sed '/^$/d' file.txt
sed '/^[ \t\n]/d' file.txt
3.6 🔄 替换并引用匹配的文本
sed 's/foo/[&]/g' file.txt
sed -E 's/([0-9]{3})-([0-9]{3})-([0-9]{4})/(\1) \2-\3/g' file.txt
3.7 🖨️ 打印匹配模式的行
sed -n '2p' file.txt
sed -n '2,4p' file.txt
sed -n '/foo/p' file.txt
3.8 🗑️ 条件处理和多行操作
sed '/foo/a\Found foo' file.txt
sed '/foo/{s/foo/bar/g;};/foo/!{s/$/baz/;}' file.txt
sed '/foo/{N;d;}' file.txt
sed 'N;s/\n/ /' file.txt
3.9 🗂️ 读取和写入文件
sed 'r content.txt' file.txt
sed -n '/foo/w output.txt' file.txt
3.10 🖥️ 在脚本中使用 sed
#!/bin/bash
input="input.txt"
output="output.txt"
sed 's/foo/bar/g' "$input" > "$output"
sed -e 's/foo/bar/g' -e '/baz/d' "$input" > "$output"
3.11 🌐 结合其他命令使用
3.11.1 使用管道将其他命令的输出传递给 sed
ls | sed 's/\.txt$/.bak/'
3.11.2 在脚本中结合使用 sed 和其他命令
#!/bin/bash
sed 's/foo/bar/g' file.txt | grep 'pattern'
3.12 📂 处理大文件
3.12.1 使用 sed 处理大文件时,可以结合其他工具提高效率
awk '/pattern/' bigfile.txt | sed 's/foo/bar/g'
3.12.2 使用 sed 进行批量处理
for file in *.txt; do
sed -i 's/foo/bar/g' "$file"
done
4️⃣ 综合示例
4.1 🗑️ 条件处理和多行操作
sed '/foo/a\Found foo' file.txt
sed '/foo/{s/foo/bar/g;};/foo/!{s/$/baz/;}' file.txt
sed '/foo/{N;d;}' file.txt
sed 'N;s/\n/ /' file.txt
4.2 📂 处理大文件
4.2.1 使用 sed 处理大文件时,可以结合其他工具提高效率
awk '/pattern/' bigfile.txt | sed 's/foo/bar/g'
4.2.2 使用 sed 进行批量处理
for file in *.txt; do
sed -i 's/foo/bar/g' "$file"
done
4.3 🔄 高级替换和引用
4.3.1 使用 & 引用匹配的文本
sed 's/foo/[&]/g' file.txt
4.3.2 使用 \1, \2, … 引用捕获组
sed -E 's/([0-9]{3})-([0-9]{3})-([0-9]{4})/(\1) \2-\3/g' file.txt
4.15 🌟 综合示例
4.15.1 处理多行模式
sed 'N;s/\n/ /' file.txt
sed '/foo/{x;d;}; x' file.txt
4.15.2 在特定行前后添加内容
sed '5i\Start of section' file.txt
sed '5a\End of section' file.txt
4.15.3 删除文件中的特定模式及其后面的几行
sed '/pattern/{N;N;d;}' file.txt
4.15.4 逆序文件中的行
tac file.txt | sed '1!G;h;$!d'
5️⃣ 使用 sed 进行文本分析
5.1 🧮 统计文件中包含特定模式的行数
grep -c 'pattern' file.txt
5.2 📊 统计文件中每个单词出现的次数
tr -cs '[:alnum:]' '[\n*]' < file.txt | sort | uniq -c | sort -nr
awk '{for(i=1;i<=NF;i++) count[$i]++} END{for(word in count) print word, count[word]}' file.txt
5.3 🔍 查找并替换多行模式中的特定模式
sed '/start/,/end/{s/foo/bar/g}' file.txt
5.4 🔍 查找并替换包含特定模式的行
sed '/pattern/s/foo/bar/g' file.txt
5.5 🔍 查找并替换特定行范围内的模式
sed '3,5{s/foo/bar/g}' file.txt
5.6 🔍 使用 sed 进行条件替换
sed '/pattern1/s/foo/bar/' file.txt
sed '/pattern2/!s/foo/baz/' file.txt
6️⃣ 使用 sed 处理日志文件
6.1 🔍 查找并替换日志文件中的特定模式
sed 's/ERROR/WARNING/g' logfile.log
6.2 🗑️ 删除日志文件中的特定日期范围内的日志
sed '/2023-01-01/,/2023-01-31/d' logfile.log
6.3 🔍 提取日志文件中的特定模式
sed -n '/ERROR/p' logfile.log
6.4 🔄 替换日志文件中的时间戳格式
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2})/\2\/\3\/\1 \4/' logfile.log
6.5 🗂️ 将日志文件中的错误级别重新排序
sed -E 's/(ERROR|WARNING|INFO)/\U&/g' logfile.log | sort -r
6.6 📊 统计日志文件中每种错误级别的次数
grep -Eo 'ERROR|WARNING|INFO' logfile.log | sort | uniq -c
7️⃣ 使用 sed 进行文件格式转换
7.1 🔄 将文件中的所有大写字母转换为小写字母
sed 's/.*/\L&/' file.txt
7.2 🔄 将文件中的所有小写字母转换为大写字母
sed 's/.*/\U&/' file.txt
7.3 🔄 将制表符转换为空格
sed 's/\t/ /g' file.txt
7.4 🔄 将空格转换为制表符
sed 's/ \{1,\}/\t/g' file.txt
7.5 🔄 将 CSV 文件转换为 TSV 文件
sed 's/,/\t/g' file.csv
7.6 🔄 将 TSV 文件转换为 CSV 文件
sed 's/\t/,/g' file.tsv
8️⃣ 使用 sed 进行数据清洗
8.1 🗂️ 交换特定列的数据
awk -F, '{temp=$2; $2=$4; $4=temp; OFS=","; print}' file.csv
9️⃣ 参考资料