官方说明: https://www.gnu.org/software/sed/manual/sed.html
sed 是 stream editor 的缩写, 即流编辑器
命令格式: sed [option] addressCommand file
执行流程可以简单理解为以下伪代码:
while(文件未结束){
读取下一行内容 => 模式空间
根据`address`对命令进行匹配, 如果匹配则根据`command` 对模式空间的内容处理, 如果未匹配不处理
打印当前处理后的行到标准输出流(如果-n则只有改行匹配时才会打印)
清空模式空间(将模式空间的内容赋值给保留空间)
}
注意这里command
默认只有一个命令, 也可以有连续执行多个命令(此时用{}
(有时也可省略)扩起来, 命令之间用;
隔开)
-n: 选项经常和 p 配合使用,其含义就是,输出那些匹配的行。
-E: 使用扩展的regex正则表达式
-e: 包含多个 command(也可同时执行), 如
sed -n -e '1,2p' -e '4p'
(等同于sed -n -e '1,2p;4p'
)-f: 如果
addressCommand
部分比较复杂, 可以写到文件中读取,sed -n -f command.txt temp.txt
-i: 直接编辑原文件,默认不对原文件进行操作
- startLine,EndLine: 第startLine行到第endLine行,如1,100
- /regexp/: 匹配正则表达式,如/^root/
- /pattern1/,/pattern2/: 第一次匹配到pattern1的行,到第一次匹配到pattern2的行结束,这中间所有的行
- lineNum:如1,其他指定的行,$表示最后一行
- startLine,+N: 从startLine开始,向后N行
- 0, /regexp/:从起始行开始到第一次能够被regexp匹配到的行
first~step
:指定起始的位置及步长,例如:1~2表示1,3,5…- /pattern/! : 条件取反
$!
: 最后一行不处理(常用)
p: 将命中行打印, 常和-n配合使用(不带-n为什么会打印两次参考前面的执行流程)
s: 将命中行进行替换。
d: 将命中行进行删除
a: 将命中的行的下一行, 插入指定文件的内容
i: 将命中的行的上一行, 插入指定文件的内容
r: 对命中的行, 将指定文件的内容添加至下一行
w: 将命中行, 将指定范围内的内容另存至指定的文件中
y: 和s相似, 将命中行每个字符进行一一映射替换
c: 将命中的行直接进行内容替换
sed -n '1,5p' temp.txt
#打印前5行
sed -n '5,+2p' temp.txt
#打印前5,6,7行
sed -n '/^[0-9]\+/p' temp.txt
#打印以数字开始的行
s命令的完整用法: /reg1/s/reg2/replace/flages
:查找替换, 满足reg1
的行进行将reg2
替换为replace
其中replace通常为固定的字符窜, 但可能包含特殊字符
\L:转换后, replace中后面紧接的内容全部为小写, 如
s/1/ab\LCDE/
等价于s/1/abcde/
\l:转换后, replace中后面紧接的内容第一个字符为小写,直到遇到\E为止, 如
s/1/ab\lCDE/
等价于s/1/abcDE/
\U:转换后, replace中后面紧接的内容全部为大写, 如
s/1/ab\Ucde/
等价于s/1/abCDE/
\u:转换后, replace中后面紧接的内容第一个字母为大写,直到遇到\E为止, 如
s/1/ab\Ucde/
等价于s/1/abCde/
\E:当以\L或\U开始的时候,\E意味着停止字符的转换
&: 表示
reg2
命中的整体内容, 作为变量可以直接引用\#: 表示在
reg2
中通过()
预存储的变量
常用的flages:
g:全局替换,默认只替换第一个
i: 不区分大小写p:如果成功替换则打印
sed 's/a/A/' temp.txt
#将a
替换成A
sed '/^[0-9]\+/s/^\([0-9]\+\).*/\1/' temp.txt
#以数字开始的行, 仅保留行首的数字
sed '1,2d' temp.txt
#删除前两行
sed '/^[0-9]/d' temp.txt
#删除以数字开始的行
sed '/2/d' temp.txt
#删除带2
的行
在命中行的下一行, 插入指定内容content
sed '1,2a\content' temp.txt
在命中行的上一行, 插入指定文件的内容content
sed '1,2i\content' temp.txt
在命中行的下一行, 插入指定文件的内容
已知ins.txt
的内容为=======
sed '1,2r ins.txt' temp.txt
将命中的行写入到指定文件
sed '/^[0-9]/w new.txt' temp.txt
#将以数字开头的行, 输入到文件new.txt
将字符一一映射替换(y的两个参数长度必须相同)
echo "hello world" | sed 'y/abcdefghij/0123456789/' #a替换为0,b替换成1以此类推
74llo worl3
将匹配的行直接进行内容替换
sed '1c \content' temp.txt
示例temp.txt
文件:
111111
222222
333333
1111aa
abcdef
444444
555555
666666
777777
888888
999999
sed不仅存在模式空间, 也存在一个保持空间(hold space)。
顾名思义,保存空间是一段sed独有的内存空间片段,可以暂时存放一些数据(默认情况下存放上一行的模式空间)
其中与“保持空间”相关的编辑命令有:
h:把模式空间中的内容覆盖到保存空间中的内容
H:把模式空间中的内容追加到保存空间中(加在原有内容之后)
g:把保持空间中的内容覆盖到模式空间中的内容
G:把保持空间中的内容追加到模式空间中(加在原有内容之后)
x:把模式空间中的内容和保持空间中的内容进行交换 示例sed -n 'x;p' temp.txt
d:删除模式空间中的内容, 比较sed 'n;d' temp.txt
和sed -n 'n;d' temp.txt
D:如果模式空间中的内容为多行时,删除模式空间中的第一行, 比较sed 'n;D' temp.txt
和sed -n 'n;D' temp.txt
n:读取匹配到的行的下一行到模式空间中(覆盖原内容), 比较 sed 'n;p' temp.txt
和sed -n 'n;p' temp.txt
N:读取匹配到的行的下一行到模式空间中(追加在原内容之后), 比较 sed 'N;p' temp.txt
和sed -n 'N;p' temp.txt
p: 打印当前的pattern space
P: 打印当前的pattern space中的第一行
q 退出sed,可以增加执行速度
l 列出当前行,包含不可打印字符
l width 列出当前行,使用一个width characters
结尾
b label 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾
t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。测试命令。
T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
b 分支命令基本格式为:
[address]b [label]
通常与标签一起使用: 表示如果满足adress
条件则执行lable
标签对应的代码, 否则不执行
b可以向前跳(标签定义在前), 也可以向后跳(标签定义在后)
定义标签用:labName
t分支命令格式
[address]t [label]
https://blog.csdn.net/weixin_58130165/article/details/120332454
https://blog.51cto.com/u_3078781/3287462
https://blog.51cto.com/u_15147537/5618194
https://www.gnu.org/software/sed/manual/sed.html
https://zhuanlan.zhihu.com/p/67977952
https://zhuanlan.zhihu.com/p/514143451
sed -n '/正则表达式/p' file
和grep -n '正则表达式' file
作用相同
sed '/AA/s/BB/CC/g'file 或 sed '/AA/s/BB/CC/'file
匹配到文件中带有 AA 的行,并且将这些行中所有的 BB 替换成 CC, 带g
表达式替换所有, 不带g
表示替换只第一个
其中BB
中支持()
语法预存匹配内容, 并在CC
中通过\1
, \2
等变量引用直接引用
如果需要提取BB
命中的所有内容, 用&
即可
sed -n '1~2p' temp.txt
#奇数行打印
sed -n '2~2p' temp.txt
#偶数行打印
sed 's/[a-z]\+/\U&/g' temp.txt
将字母完全替换为大写(&
表示[a-z]\+
命中的内容本身)
sed 's/[A-Z]\+/\L&/g' temp.txt
将字母完全替换为小写(&
表示[A-Z]\+
命中的内容本身)
同一个表达式中连续执行多个命令(此时用{}
(有时也可省略)扩起来, 命令之间用;
隔开)
如sed -n -e '1,2p;4p' temp.txt
sed '/^#/d' temp.txt
#仅显示不以#
开头的行(即删除以#
开头的行)
或/pattern/!
来作为adress
sed -n '/^[0-9]/{n;p;}' temp.txt
隔行打印
sed -n '/^[0-9]/{n;s/a/A;}' temp.txt
隔行进行s
替换
其中n
的真实作用是将下一行内容放到处理缓存中
将空格和tab删除
sed 's/\s//g'
即可,其中\s
命中空格键和tab键
达到trim的效果
sed 's/^\s*//;s/\s*$//' totrimStr
合并所有行为一行
sed ':lab;N;s/\n/,/;t lab' temp.txt
#将多行合并成一行,用指定的逗号拼接
如果需要选择的行, 可以和grep
结合使用
sed -i 's/old_string/new_string/g' filename
理解:
:lab
表示定义一个标签, 名称为lab
N
读取下一行
t tab
表示退出标签tab
正则不支持\d
, 可以用[0-9]
正则表达式里{}()+*?"
等都要用\
转义
http://c.biancheng.net/linux/sed.html
http://lnmp.ailinux.net/sed