目录
同作为文本编辑三巨头之一的sed同样有许多强大的功能,可根据指定的条件对文本内容进行删除、替换、添加等,也可以在无交互的情况下实现相当复杂的文本处理操作。
sed工作流程
当用户键入命令的那一刻,sed从输入流中读取一行内容并存储到临时的缓冲区(又称模式空间)中,然后sed根据用户的命令,对模式空间中的内容按顺序进行处理(如果没有特别指定某行的话),处理完模式空间中的内容后,sed会将模式空间中的内容输出到标准输出或指定的文件中。至此一套流程就走完了,模式空间也没什么好特别说明的,就是 sed 内部用于存储当前处理行的临时缓冲区。
操作参数
sed 的用法和常规的命令大体相同,有两种格式
sed [选项] [操作] [参数]
sed [选项] -f scriptfile 参数 scriptfile是sed的文件名,一般就用第一个就可以了
常用的选项参数有
-e:表示用指定命令或脚本来处理输入的文本文件
-f:表示用指定的脚本文件来处理输入的文本文件
-n:表示仅显示处理后的结果
-i.bak:直接编辑文本文件
-r (-E) :使用扩展正则表达式
-s:将多个文件视为独立文件 ,而不是单个连续的长文件流
常用的操作有
a:增加,在当前行下面增加一行
c:替换
d:删除
i:插入,在选定行上面插入
p:打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容;如果有非打印字符,则以 ASCII 码输出。其通常与“-n”选项一起使用,n 读取下一行到模式空间
s:替换,替换指定字符
y:字符转换
sed命令的使用
1.条件输出
sed命令常用的操作参数就这么多,纸上得来终觉浅,主要还是记住了之后会使用,基本操作都是大同小异的,咱们还是通过大(shao)量的案例来加深对sed命令的理解与印象。
我们依旧用之前练习grep命令时候的测试文档,考虑到可能有的小伙伴是直接从sed开始学习的话,我再将那个文档复制一遍,直接在随便一个位置创建一个文档,然后粘贴即可食用
#123.txt
his is a test file for grep command.
t contains various patterns and special characters.
asic characters: abc, def, ghi
2. Digits: 123, 456, 789
3. Special characters: ., *, +, ?, ^, $, [, ], {, }, |, (, )
4. Word boundaries: start, end, middle
on-word characters: @, #, %, &, !
scaped characters: \., \*, \+, \?, \^, \$, \[, \], \{, \}, \|, \(, \)
ultiple lines with the same pattern:
pattern
pattern
pattern
Case sensitivity: Case, case, CASE
Whole word matching: word, sword, reword
hole line matching: This is a whole line.
ontext lines:
This is line before the match.
his is the matching line.
This is line after the match.
ile names: file1.txt, file2.txt, file3.txt
Directory names: dir1, dir2, dir3
xclude patterns: exclude this line
Include patterns: include this line
ecursive patterns:
./dir1/file1.txt
./dir2/file2.txt
./dir3/file3.txt
olor highlighting: highlight this
ount matching lines: count this line
Matching groups: group1, group2, group3
on-matching groups: nongroup1, nongroup2, nongroup3
ll
lol
lool
loool
loooool
looooool
looooooool
loooooooooooooooooool
lo+l
首先是 sed -n 'p' 123.txt 命令,这个命令等同于cat 123.txt -n显示 p 是打印,没有特指
来点特指吧,打印六到十行的内容
sed -n '6-10p' 123.txt 如果是只打印某一行,那就直接行号加个 p 就可以了
假如有特殊需求,需要打印奇数行或者偶数行,该如何做呢?
这就需要用到 p 操作后面补充的 n 操作,我们打印一行,将一行放入到模式空间,以此反复,不就是打印出奇数行或者偶数行了吗?
如果是 sed -n '{p;n}' 123.txt 那就是,先打印,再将下一行放入模式空间,也就是打印出奇数行
相反的 sed -n '{n;p}' 123.txt 就是先放入再打印,也就是打印出偶数行
sed 中也有 ^ 头 $ 尾的用法,比如我们没有确认最后一行是多少行,但是现在立马就需要打印从第二十行到最后一行,那么就直接 sed -n '20,$p' 123.txt
我们可以结合一些其他命令食用,效果更佳
直接打印查看网卡的第二行内容,一目了然
当然,sed 命令同样也可以实现过滤筛选的功能,比如我要输出含有 hole 的行
sed -n '/hole/p' 123.txt 和grep不同的是 正则表达式不在[ ]里了 而在 / /里
现在,我只需要前面几行,到那个3. 4. 什么开始的,之后我都不需要
sed -n '1,/2/p' 123.txt 可以输出从第一行开始一直到第一个出现 2 的行
然后我们将 p 换成 "=" 就可以看到刚才输出了多少行,如果从什么什么开头的行到结尾,那就是
比如从 ll 到最后一行 sed -n '/ll/,$p' 123.txt
像grep 命令那样,输出以什么什么开头的行,以什么什么结尾的行,也是一个道理
sed -n '/^[0-9]/p' 123.txt 输出以数字开头的行
sed -n '/[a-z]$/p' 123.txt 输出以字母结尾的行
2.删除
除此之外,sed 可以做到额外grep不能做到的,就是删除、替换等
如何删除符合条件的文本呢?
假如我需要删除第几行,就直接 sed -n '行号d' 123.txt 就可以直接删除指定的行,这里可以随便创建一个短一点的文件测试一下 sed -n '1d' 123.txt
执行完操作后我们会发现,怎么第一行的helloworld还在?
我们回过头去看-n 的注释,显示输出后的结果,说明事实上并未执行操作,如果真的确定了想要删除改动源文件,那么把 -n 改成 -i 就可以了,不放心的话可以加上“,bak” ,把源文件做一个备份
上面进行的打印多少到多少行,以什么什么开头的行,都相应的可以执行删除操作,只需要将后面的p改成d 就可以了,我就稍微举一个例子吧,多余的我也就不一一列出来了
删除包含 a 的行 删除以数字结尾的行
sed -i '/a/d' hh.txt sed -i '/[0-9]$/d' hh.txt
3.替换
接下来是替换文本,和文本编辑器里的查找替换有点类似
sed 's/w/W/' 123.txt 将每行的第一个w替换成W,当然,如果想要操作对源文件也生效的话,需要在前面加上 -i ,同样的,如果不确定或者不放心,可以先不加 -i 试看一下操作结果,或者加上,bak 将文件备份
如果需要替换每一行中的第几个w 就在最后一个/后面加上数字几
和文本编辑器同理,如果想要替换所有的,那么就是 's/w/W/g' 可以替换全局
sed 's/o/W/g' 123.txt
o都变成W了
其实替换操作,也可以变相地实现删除
思考一下,假如一个文件里的字符都被删了,那么这个文件剩下什么?什么也不剩下,那不就说明文件空了吗?那我只要把需要删除的字符,替换成空,就可以实现删除了
sed 's/o//g' 123.txt 把o都变成空
由于文件太长了,没法连命令一起截图,我就截了最后面那块,最明显的效果图
sed '/[A-Z]/s/^/#/' 123.txt 在包含大写字母的每行行首插入 # 号
如果想要所有行都插入#,那么把前面的/[A-Z]去掉即可,行尾的话也是将^改成$即可
4.迁移
迁移操作相对来说要难一点,但也仅仅是难一点,直接通过一些操作来解释吧
假如我需要把包含数字的行都放到文件末尾
sed '/[0-9]/{H;d};$G' 123.txt
可以看到,带有数字的行都被放到最后面去了,那么问题来了,'/[0-9]/{H;d};$G' 这一大坨是什么玩意呢?
其实都是固定搭配,记住就好了,但是还是一一解释一下,更方便理解记忆
/[0-9]/就不用多解释了吧,筛选数字用的,/ /将正则表达式包起来
{H;d} 将当前模式空间的内容追加到保持空间,删除当前模式空间的内容,并跳过剩余的脚本,开始处理下一行
$ 末尾
G 将保持空间的内容追加到当前模式空间,其实也可以见到粗暴的理解为多少行,比如将1-5行的内容放到20行后面就是 sed '1,5{H;d};20G' 123.txt
sed '/[0-9]/w num.file' 123.txt 将包含数字的行另存为文件 num.file
这个操作和文本编辑器里的操作又有点像了,那这是不是说明了,也可以将别的文件里的内容放到指定行后面
恭喜你,答对了,确实有种操作,我们来创建一个内容很明显的文件 hh.txt
可以,非常明显,我爱刀乐(但是爱国)
sed '/[0-9]/r /opt/hh.txt' 123.txt 将hh.txt 里的内容插入到123.txt 文件内含有数字的行后面
非常成功,[0-9]作为筛选条件 可以自由进行发挥
sed '3aNew' 123.txt 在第 3 行后插入一个新行,内容为New,这种简单的照敲就好了,不 演示了
同样的也可以特定指定含有某些内容的行下面进行插入
5.脚本编辑
这么多操作,如果对多个文件都要进行相同的操作,那不得累死,这时候我们便想到了脚本,我们提前在比如 seddemo.txt 里编辑好命令操作
s/sb/*/g 将sb都替换为*号
/250/d 将250都删掉
然后 sed -f seddemo.txt 123.txt
就可以对123.txt 文件执行刚才编辑的操作了,亲测有效,自己操作一下吧
其他的sed可以正确执行的操作,都可以放入文件,用来对另一文件进行编辑,当然,毕竟是脚本,上一条命令执行成功了才能再执行下一条命令
sed的命令操作很多很杂,需要多家练习才能熟稔于心
awk命令之后整理好了我也会发出来