文章目录
sed 编辑器
sed
是一种流编辑器(Stream Editor),用于对文本文件进行行级别的处理。与 vim
不同,sed
处理时不直接编辑文件,而是将文件的每一行读取到临时缓冲区中(称为“模式空间”或 pattern space),在该缓冲区中执行编辑命令,最后将处理结果输出到屏幕或指定的文件。
工作过程
sed
的工作流程包括以下三个主要步骤:
- 读取:
sed
从输入流(文件、管道、标准输入)中读取一行内容并存储到临时缓冲区(模式空间)中。 - 执行:
sed
在模式空间中执行指定的命令,对内容进行相应处理。默认情况下,所有sed
命令都会顺序执行,除非指定了行的地址范围。 - 显示:将修改后的内容输出到标准输出或指定的文件。在输出之后,模式空间被清空并重复上述过程,直至所有输入内容处理完毕。
注意:默认情况下,sed 不会修改源文件内容,除非使用 -i 选项直接编辑文件或使用重定向将输出保存到新文件中。
提高 sed 执行效率的方法
在处理大容量文件时,sed
的执行速度可能会变慢。优化方案:
-
方案一(推荐使用):使用
split
命令将大文件按行数或大小进行拆分,然后对拆分后的文件分别执行sed
操作。示例:
# 将一个百万行的文件拆分为每个文件10000行的小文件 split -l 10000 largefile.txt smallfile_ # 按行分割 # 用行开分割更直观,推荐工作中使用 split -l -30 test1.txt se # 按大小分割 split -b 400M test1.txt se
-
方案二:使用
cat 文件名 | sed 处理命令
的方式处理文件。这种方法适用于中大型文件,但对于非常大的文件效果不佳。
sed 命令格式与选项
格式
sed '/匹配模式/命令 参数' 文件名
基本操作格式
sed -e '操作' 文件1 [文件2]
# 使用 -e 选项指定编辑操作
sed -f 脚本文件 文件1 [文件2]
# 使用 -f 选项从脚本文件读取操作
sed -i -e '操作' 文件 [文件2]
# 直接编辑文件(慎用)
执行多条命令
方式一:
sed -e '操作1' -e '操作2' 文件
# 例如
sed -n -e '/^r/p' -e '/^b/p' /etc/passwd
方式二:
sed -e '操作1;操作2' 文件
常用选项
- -e 或
--expression=
:指定处理输入文件的 sed 命令。只有一个操作命令时可省略,一般在执行多个操作命令使用。 - -f 或
--file=
:使用指定的脚本文件读取 sed 命令。 - -h 或
--help
:显示帮助信息。 - -i :直接修改目标文件(慎用)。(in-place)
- -n:禁止默认输出,仅显示 sed 处理后的结果,通常与p命令结合使用。
- -r :支持扩展正则表达式。(-E也可以,主要在BSD系统。)
常用操作符(也叫命令)
s
:替换,替换指定字符。d
:删除,删除指定的行。a
:增加,在当前行之后添加一行。i
:插入,在当前行之前插入一行。c
:替换,将选定行替换指定的行。y
:字符替换,转换前后的字符长度必须相同。p
:打印行。如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以 ASCII 码输出。通常与“-n”选项一起使用。=
:打印行号。l
:打印文本行,显示不可打印的 ASCII 字符(比如结束符$、制表符\t)r
:从另一个文件中读取内容并插入到指定行之后。
分隔符 / 格式说明
在 sed
命令的语法规则中,正则表达式通常用正斜杠 /
来分隔,用于将模式和命令分隔开来。
-
语法结构:
sed
命令的基本格式是sed 's/pattern/replacement/'
或者类似的形式,如sed '/pattern/command'
。其中,/
用来分隔正则表达式(模式)和命令部分。例如:/pattern/
用于定义一个正则表达式的匹配模式。s/pattern/replacement/
用于替换模式匹配到的内容。
-
可以更换分隔符:实际上
/
并不是唯一的,可使用其他字符作为分隔符,只要在整个命令中保持一致。例如,#
可以用作分隔符,适合用于匹配带有斜杠的路径的情况:sed '\\#^/usr/local#d' file.txt # # 用于替代 / 作为分隔符。
地址定界
sed
命令中的地址定界(addressing)用于指定在哪些行上应用给定的操作。地址定界可以是具体的行号、行范围或匹配模式。sed
根据这些地址定界确定在哪些行上执行操作。
地址定界的类型
- 行号:指定特定的行。
- 示例:
sed '2d' file.txt
删除第2行。
- 示例:
- 行范围:指定一个行的范围(从某一行到另一行)。
- 示例:
sed '2,4d' file.txt
删除从第2行到第4行的所有行。
- 示例:
- 匹配模式:基于内容匹配来指定行。
- 示例:
sed '/pattern/d' file.txt
删除包含 “pattern” 的所有行。
- 示例:
- 地址和操作的组合:将操作应用于匹配模式和/或特定行号的组合。
- 示例:
sed '1,3s/foo/bar/' file.txt
将第1行到第3行中所有的 “foo” 替换为 “bar”。
- 示例:
sed 的核心功能
sed
具有增(增加)、删(删除)、改(替换)、查(打印)四大核心功能。
打印功能( p , = , l 命令)
sed
命令可以用来查看文件内容,支持重定向输入和管道符的使用。
sed '' /etc/fstab # 查看文件内容
sed '' < /etc/fstab # 使用重定向输入查看文件内容
cat /etc/passwd | sed '' # 使用管道符查看文件内容
示例
-
默认打印方式
sed
默认会输出所有内容,使用-n
选项可以禁止默认输出,配合p
选项打印指定的行。sed -e 'p' test1.txt # 默认输出加上'p'会打印两行 sed -n 'p' test1.txt # 使用'-n'禁止默认输出,只打印一行 sed -n '2p' test1.txt # 打印第二行
-
打印行号和内容
sed -n '=' test1.txt # 只显示行号 sed -n '=;p' test1.txt # 显示行号和每行的内容
-
寻址打印
-
方式一:按照行号打印
sed -n '1p' test1.txt # 打印第一行 sed -n '4p' test1.txt # 打印第四行 sed -n '$p' test1.txt # 打印最后一行
-
方式二:打印行号范围区间
sed -n '1,3p' test1.txt # 打印1-3行 sed -n '5,$p' test1.txt # 打印第五行到最后一行 sed -n '2,+2p' test1.txt # 打印第二行和之后的两行,相当于 2,4p sed -n '3p;5p' test1.txt # 打印第三行和第五行
-
方式三:指定间隔打印
sed -n -e '2p' -e'$p' test1.txt # 打印第二行和最后一行 sed -n -e '2p' -e'3p' test1.txt # 打印第二行和第三行
-
方式四:打印奇数行和偶数行
n 在 p 前面,跳过一行,打印下一行,就是偶数行
n 在 p 后面,就是打印第一行,然后跳过一行,形成奇数行
sed -n 'n;p' test1.txt # 打印偶数行 sed -n 'p;n' test1.txt # 打印奇数行
- 文本模式过滤行内容打印
-
方式一:对包含字符串的行进行过滤打印
sed -n '/o/p' test1.txt # 打印包含 'o' 的所有行 sed -n '/th/p' test1.txt # 打印包含 'th' 的所有行
-
方式二:应用基础正则表达式进行打印
sed -n '/^root/p' /etc/passwd # 打印以 'root' 开头的所有行 sed -n '/bash$/p' /etc/passwd # 打印以 'bash' 结尾的所有行 sed -n '4,/bash$/p' /etc/passwd # 从第四行开始,一直打印到第一个以bash为结尾的所在行
-
方式三:应用扩展正则表达式进行打印
注意:
sed -r
支持扩展正则表达式。同时在使用{n}
、{n,}
、{n,m}
时,括号{}
前不需要加反斜杠\
。sed -r -n '/(99:){2,}/p' /etc/passwd # 打印包含有两个 '99:' 的行 sed -r -n '/^root|bash$/p' /etc/passwd # 打印以 'root' 开头或以 'bash' 结尾的行
删除操作( d 命令)
注意:sed -i
时会对文本进行实际操作,建议对目标文件先进行备份,再进行操作。
示例
-
通过行号进行删除
sed 'd' test1.txt # 删除所有行,什么也不打印 sed -n '3d;p' test1.txt # 删除第三行,打印剩余内容 sed -n '5,8d;p' test1.txt # 删除5到8行,打印剩余内容 sed -n '5,$d;p' test1.txt # 删除5到最后一行,打印剩余内容 sed '4,6!d' test1.txt # 除了4-6行,其他的全部删除 # 如果要生效:sed -i -n
-
匹配字符串内容删除
sed '/one/d' test1.txt # 删除包含 'one' 的行 sed '/one/,/six/d' test1.txt # 删除 'one' 到 'six' 之间的行 sed '/one/,/six/!d' test1.txt # 反向删除,除了one-six的行,其余的全部删除 sed '/six/!d' test1.txt # 反向删除,除了six的行,其余的全部删除
-
字符串搭配正则进行删除
sed '/^$/d' test1.txt # 通过^$,来删除空行;
-
删除空行
# 方法一: grep -v "^$" test1.txt # 过滤出非空行 # 方法二: cat test1.txt |tr -s "\n" # 压缩换行符 # 方法三: sed '/^$/d' test1.txt # 删除空行
替换操作( s , c , y 命令)
格式
sed
使用 s
操作符进行替换:
行范围 s/旧字符串/新字符串/替换标记
示例
sed 's/旧字符串/新字符串/' test1.txt
# 替换第一处匹配
sed 's/旧字符串/新字符串/g' test1.txt
# 替换所有匹配
替换标记和替换命令:
-
替换标记(Flags)
在
sed
的替换操作(s
命令)中使用的是替换标记(flags)。这些标记用来指定替换的行为,通常放在s/old/new/
之后。 -
替换命令(Commands)
用于不同的替换操作,指定替换操作的类型。它们是sed
的主要操作指令,通常紧跟在分隔符/
后面。
常用替换标记
数字
:新字符串替换第几处匹配。g
:新字符串替换所有匹配。(global)p
:打印替换后的行。与“-n”一起使用。w 文件
:将替换结果写入文件。
常用替换命令
s
:替换字符串。(substitute)c
:整行替换。y
:字符替换,替换前后的字符串长度必须相同。
特殊转换符号
\l
:将紧随其后的字母转换为小写。- 例:
sed 's/[A-Z]/\l&/g' file.txt
将所有大写字母转换为小写字母。
- 例:
\u
:将紧随其后的字母转换为大写。- 例:
sed 's/[a-z]/\u&/' file.txt
将匹配的第一个小写字母转换为大写字母(仅对每个替换的第一个匹配字符有效)。
- 例:
\L
:将紧随其后的所有字母转换为小写。- 例:
sed 's/[a-z]/\L&/g' file.txt
将所有匹配的字母转换为小写字母。
- 例:
\U
:将紧随其后的所有字母转换为大写。- 例:
sed 's/[a-z]/\U&/g' file.txt
将所有匹配的字母转换为大写字母。
- 例:
其他操作符号
&
:在替换操作中匹配的整个模式。因此,它可以用来引用正则表达式匹配到的内容。|
:在扩展正则表达式中表示或操作。
示例
-
直接替换字符串( s 命令)
sed -n 's/root/test/2p' /etc/passwd # 指定第二个 "root",替换为 "test" sed -n 's/root/test/gp' /etc/passwd # 所有的 "root" 都替换为 "test" sed -n '/^root/ s/^/#/p' /etc/passwd # 以"root"开头的行,替换开头为空的字符为"#"
将文件中“/var/www/”的内容替换为“/etc/”
sed "s/\/var\/www/\/etc/" httpd.conf
-
字母字符大小写转换
sed
可以用于转换字母的大小写:将大写字母转换为小写:
“l&” 是转换小写的特殊符号
sed 's/[A-Z]/\l&/g' test1.txt # 将所有大写字母转换为小写, # "l&" 是转换小写的特殊符号,需加转义符 "\"
将首字母转换为大写:
“u&” 是转换首字母大写的特殊符号
sed 's/[a-z]/\u&/' test1.txt # 将首字母替换为大写, # "u&" 是转换首字母大写的特殊符号,需加转义符 "\"
将所有小写字母转换为大写:
末尾加上 “g”
sed 's/[a-z]/\\U&/g' test1.txt # 末尾加上 "g",表示全部转换成大写
-
字符串和字符位置交换
通过正则表达式的分组和引用,
sed
可以轻松实现字符串或字符位置的交换。echo ky29ztt | sed -r 's/(ky29)(ztt)/\2\1/' # 输出:zttky29 echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\3\2\1/' # 输出:dxlyhtky27 echo ky27yhtdxl | sed -r 's/(ky27)(yht)(dxl)/\3\2/' # 输出:dxlyht echo 123abc | sed -r 's/(.)(.)(.)(.)(.)(.)/\6\5\4\3\2\1/' # 输出:cba321 echo 小明明真的帅 | sed -r 's/(.)(.)(.)(.)(.)(.)/\6\5\4\3\2\1/' # 输出:帅的真明明小
-
整行替换( c 命令)
使用
c
命令可以替换整行的内容。sed '/ONE/c 22' test1.txt # 将包含 "ONE" 的行替换为 "22" sed '/TWO/c TEST' test1.txt # 将包含 "TWO" 的行替换为 "TEST"
-
单字符替换( y 命令)
使用
y
命令对单个字符进行替换,每个字符需要一一对应,不是整体替换。只要有匹配的单字符会全部替换。注意:前后字符串长度需要一致,否则会报错。
sed 'y/TH/12/' test1.txt # 将 "T" 替换为 "1","H" 替换为 "2"
增加功能( a , i , r 命令)
sed
支持在指定行后或前增加内容,或从文件中读取内容插入。
常用增加命令
a
:在下一行添加内容,在指定的匹配行之后插入内容。(append)i
:在上一行插入内容,在指定的匹配行之前插入内容。(insert)r
:在行后读入文件内容,从文件中读取内容并插入到指定的匹配行之后。(read)
示例:
###用法一:
sed '/three/a 123' test1.txt
# 在包含 "three" 的行后插入 "123"
sed '/three/i 123' test1.txt
# 在包含 "three" 的行前插入 "123"
sed '/three/r test.sh' 123.txt
# 在包含 "three" 的行后插入 "test.sh" 文件内容
###用法二:使用$符号匹配
sed '$r test2.txt' test1.txt
# 在 test1.txt 最后一行后插入 test2.txt 文件的内容
# $-匹配最后一行,r-读取再插入
sed '$a 123' 123.txt
# 在 `123.txt` 最后一行插入 "123",a-下一行
sed '$i 123' 123.txt
# 在 `123.txt` 倒数第二行后插入 "123",i-上一行
sed 's/$/ EOF/' 123.txt
# 使用替换,在每一行末尾添加 "EOF"
使用 -f 指定命令文件(读取规则)
sed
可以通过 -f
参数指定命令文件来处理另一个文件。
示例1:
读取 123.txt
的替换规则应用到 456.txt
。
cat 123.txt
/IPADDR=192.168.233.21/c IPADDR=10.10.10.10
cat 456.txt
IPADDR=192.168.233.21
sed -f 123.txt 456.txt
# 使用 123.txt 的命令处理 456.txt
# 结果将 IP 地址替换为 "10.10.10.10"
示例2:
使用 -f
选项从文件 test27.txt
中读取替换规则,并将这些规则应用到 test27sed.txt
文件的内容上。
cat test27.txt
s/ /_/g
cat test27sed.txt
hello world
aaa bbb
sed -f test27.txt test27sed.txt
hello_world
aaa_bbb
# s/ /_/g:用下划线(_)替换所有的空格( )。
# / /:匹配空格
# g:全局替换
标签:test1,文件,Shell,编程,打印,sed,txt,替换 From: https://blog.csdn.net/qq_44421043/article/details/142034692